Path: blob/master/src/demo/share/jfc/Font2DTest/RangeMenu.java
41152 views
/*1* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions5* are met:6*7* - Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9*10* - Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* - Neither the name of Oracle nor the names of its15* contributors may be used to endorse or promote products derived16* from this software without specific prior written permission.17*18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS19* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,20* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR21* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR22* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,23* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,24* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR25* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF26* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING27* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS28* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29*/3031/*32* This source code is provided to illustrate the usage of a given feature33* or technique and has been deliberately simplified. Additional steps34* required for a production-quality application, such as security checks,35* input validation and proper error handling, might not be present in36* this sample code.37*/383940/*41*/4243import java.awt.BorderLayout;44import java.awt.Font;45import java.awt.event.ActionEvent;46import java.awt.event.ActionListener;47import java.awt.event.ItemEvent;48import java.awt.event.ItemListener;4950import javax.swing.*;5152import java.util.*;53import java.util.regex.*;5455/**56* RangeMenu.java57*58* @author Shinsuke Fukuda59* @author Ankit Patel [Conversion to Swing - 01/07/30]60*/6162/// Custom made choice menu that holds data for unicode range6364public final class RangeMenu extends JComboBox<String> implements ActionListener {6566private static final int[][] UNICODE_RANGES = getUnicodeRanges();67private static final String[] UNICODE_RANGE_NAMES = getUnicodeRangeNames();6869private boolean useCustomRange = false;70private int[] customRange = { 0x0000, 0x007f };7172/// Custom range dialog variables73private final JDialog customRangeDialog;74private final JTextField customRangeStart = new JTextField( "0000", 4 );75private final JTextField customRangeEnd = new JTextField( "007F", 4 );76private final int CUSTOM_RANGE_INDEX = UNICODE_RANGE_NAMES.length - 1;7778/// Parent Font2DTest Object holder79private final Font2DTest parent;8081public static final int SURROGATES_AREA_INDEX = 91;8283public RangeMenu( Font2DTest demo, JFrame f ) {84super();85parent = demo;8687for ( int i = 0; i < UNICODE_RANGE_NAMES.length; i++ )88addItem( UNICODE_RANGE_NAMES[i] );8990setSelectedIndex( 0 );91addActionListener( this );9293/// Set up custom range dialog...94customRangeDialog = new JDialog( f, "Custom Unicode Range", true );95customRangeDialog.setResizable( false );9697JPanel dialogTop = new JPanel();98JPanel dialogBottom = new JPanel();99JButton okButton = new JButton("OK");100JLabel from = new JLabel( "From:" );101JLabel to = new JLabel("To:");102Font labelFont = new Font( "dialog", Font.BOLD, 12 );103from.setFont( labelFont );104to.setFont( labelFont );105okButton.setFont( labelFont );106107dialogTop.add( from );108dialogTop.add( customRangeStart );109dialogTop.add( to );110dialogTop.add( customRangeEnd );111dialogBottom.add( okButton );112okButton.addActionListener( this );113114customRangeDialog.getContentPane().setLayout( new BorderLayout() );115customRangeDialog.getContentPane().add( "North", dialogTop );116customRangeDialog.getContentPane().add( "South", dialogBottom );117customRangeDialog.pack();118}119120/// Return the range that is currently selected121122public int[] getSelectedRange() {123if ( useCustomRange ) {124int startIndex, endIndex;125String startText, endText;126String empty = "";127try {128startText = customRangeStart.getText().trim();129endText = customRangeEnd.getText().trim();130if ( startText.equals(empty) && !endText.equals(empty) ) {131endIndex = Integer.parseInt( endText, 16 );132startIndex = endIndex - 7*25;133}134else if ( !startText.equals(empty) && endText.equals(empty) ) {135startIndex = Integer.parseInt( startText, 16 );136endIndex = startIndex + 7*25;137}138else {139startIndex = Integer.parseInt( customRangeStart.getText(), 16 );140endIndex = Integer.parseInt( customRangeEnd.getText(), 16 );141}142}143catch ( Exception e ) {144/// Error in parsing the hex number ---145/// Reset the range to what it was before and return that146customRangeStart.setText( Integer.toString( customRange[0], 16 ));147customRangeEnd.setText( Integer.toString( customRange[1], 16 ));148return customRange;149}150151if ( startIndex < 0 )152startIndex = 0;153if ( endIndex > 0xffff )154endIndex = 0xffff;155if ( startIndex > endIndex )156startIndex = endIndex;157158customRange[0] = startIndex;159customRange[1] = endIndex;160return customRange;161}162else163return UNICODE_RANGES[ getSelectedIndex() ];164}165166/// Function used by loadOptions in Font2DTest main panel167/// to reset setting and range selection168public void setSelectedRange( String name, int start, int end ) {169setSelectedItem( name );170customRange[0] = start;171customRange[1] = end;172parent.fireRangeChanged();173}174175/// ActionListener interface function176/// ABP177/// moved JComboBox event code into this fcn from178/// itemStateChanged() method. Part of change to Swing.179public void actionPerformed( ActionEvent e ) {180Object source = e.getSource();181182if ( source instanceof JComboBox ) {183String rangeName = (String)((JComboBox<?>)source).getSelectedItem();184185if ( rangeName.equals("Custom...") ) {186useCustomRange = true;187customRangeDialog.setLocationRelativeTo(parent);188customRangeDialog.setVisible(true);189}190else {191useCustomRange = false;192}193parent.fireRangeChanged();194}195else if ( source instanceof JButton ) {196/// Since it is only "OK" button that sends any action here...197customRangeDialog.setVisible(false);198}199}200201private static int[][] getUnicodeRanges() {202List<Integer> ranges = new ArrayList<>();203ranges.add(0);204Character.UnicodeBlock currentBlock = Character.UnicodeBlock.of(0);205for (int cp = 0x000001; cp < 0x110000; cp++ ) {206Character.UnicodeBlock ub = Character.UnicodeBlock.of(cp);207if (currentBlock == null) {208if (ub != null) {209ranges.add(cp);210currentBlock = ub;211}212} else { // being in some unicode range213if (ub == null) {214ranges.add(cp - 1);215currentBlock = null;216} else if (cp == 0x10ffff) { // end of last block217ranges.add(cp);218} else if (! ub.equals(currentBlock)) {219ranges.add(cp - 1);220ranges.add(cp);221currentBlock = ub;222}223}224}225ranges.add(0x00); // for user defined range.226ranges.add(0x7f); // for user defined range.227228int[][] returnval = new int[ranges.size() / 2][2];229for (int i = 0 ; i < ranges.size() / 2 ; i++ ) {230returnval[i][0] = ranges.get(2*i);231returnval[i][1] = ranges.get(2*i + 1);232}233return returnval;234}235236private static String[] getUnicodeRangeNames() {237String[] names = new String[UNICODE_RANGES.length];238for (int i = 0 ; i < names.length ; i++ ) {239names[i] = titleCase(240Character.UnicodeBlock.of(UNICODE_RANGES[i][0]).toString());241}242names[names.length - 1] = "Custom...";243return names;244}245246private static String titleCase(String str) {247str = str.replaceAll("_", " ");248Pattern p = Pattern.compile("(^|\\W)([a-z])");249Matcher m = p.matcher(str.toLowerCase(Locale.ROOT));250StringBuffer sb = new StringBuffer();251while (m.find()) {252m.appendReplacement(sb, m.group(1) + m.group(2).toUpperCase(Locale.ROOT));253}254m.appendTail(sb);255return sb.toString().replace("Cjk", "CJK").replace("Nko", "NKo");256}257}258259260