ComponentFactory.java
     1: //========================================================================================
     2: //  ComponentFactory.java
     3: //    en:Component factory -- It creates and changes components.
     4: //    ja:コンポーネントファクトリー -- コンポーネントの作成と変更を行います。
     5: //  Copyright (C) 2003-2024 Makoto Kamada
     6: //
     7: //  This file is part of the XEiJ (X68000 Emulator in Java).
     8: //  You can use, modify and redistribute the XEiJ if the conditions are met.
     9: //  Read the XEiJ License for more details.
    10: //  https://stdkmd.net/xeij/
    11: //========================================================================================
    12: 
    13: package xeij;
    14: 
    15: import java.awt.*;  //BasicStroke,BorderLayout,BoxLayout,Color,Component,Container,Cursor,Desktop,Dimension,Font,FlowLayout,Frame,Graphics,Graphics2D,GraphicsDevice,GraphicsEnvironment,GridLayout,Image,Insets,Paint,Point,Rectangle,RenderingHints,Robot,Shape,Stroke,TexturePaint,Toolkit
    16: import java.awt.event.*;  //ActionEvent,ActionListener,ComponentAdapter,ComponentEvent,ComponentListener,FocusAdapter,FocusEvent,FocusListener,InputEvent,KeyAdapter,KeyEvent,KeyListener,MouseAdapter,MouseEvent,MouseListener,MouseMotionAdapter,MouseWheelEvent,WindowAdapter,WindowEvent,WindowListener,WindowStateListener
    17: import java.awt.image.*;  //BufferedImage,DataBuffer,DataBufferByte,DataBufferInt,IndexColorModel
    18: import java.lang.*;  //Boolean,Character,Class,Comparable,Double,Exception,Float,IllegalArgumentException,Integer,InterruptedException,Long,Math,Number,Object,Runnable,SecurityException,String,StringBuilder,System
    19: import java.net.*;  //MalformedURLException,URI,URL
    20: import java.util.*;  //ArrayList,Arrays,Calendar,GregorianCalendar,HashMap,Map,Map.Entry,LinkedList,TimeZone,Timer,TimerTask,TreeMap
    21: import java.util.regex.*;  //Matcher,Pattern
    22: import javax.swing.*;  //AbstractButton,AbstractSpinnerModel,Box,ButtonGroup,DefaultListModel,ImageIcon,JApplet,JButton,JCheckBox,JCheckBoxMenuItem,JComponent,JDialog,JFileChooser,JFrame,JLabel,JList,JMenu,JMenuBar,JMenuItem,JPanel,JRadioButton,JScrollPane,JSpinner,JTextArea,JTextField,JTextPane,JViewport,ScrollPaneConstants,SpinnerListModel,SpinnerNumberModel,SwingConstants,SwingUtilities,UIManager,UIDefaults,UnsupportedLookAndFeelException
    23: import javax.swing.border.*;  //Border,CompoundBorder,EmptyBorder,EtchedBorder,LineBorder,TitledBorder
    24: import javax.swing.event.*;  //CaretEvent,CaretListener,ChangeEvent,ChangeListener,DocumentEvent,DocumentListener,ListSelectionListener
    25: import javax.swing.plaf.metal.*;  //MetalLookAndFeel,MetalTheme,OceanTheme
    26: import javax.swing.text.*;  //AbstractDocument,BadLocationException,DefaultCaret,Document,DocumentFilter,JTextComponent,ParagraphView,Style,StyleConstants,StyleContext,StyledDocument
    27: 
    28: public class ComponentFactory {
    29: 
    30: 
    31:   //--------------------------------------------------------------------------------
    32:   //コンポーネントにリスナーを追加する
    33: 
    34:   //button = addListener (button, listener)
    35:   //  ボタンにアクションリスナーを追加する
    36:   public static <T extends AbstractButton> T addListener (T button, ActionListener listener) {
    37:     if (listener != null) {
    38:       button.addActionListener (listener);
    39:     }
    40:     return button;
    41:   }  //addListener(T extends AbstractButton,ActionListener)
    42: 
    43:   //comboBox = addListener (comboBox, listener)
    44:   //  コンボボックスにアクションリスナーを追加する
    45:   public static <T extends JComboBox<String>> T addListener (T comboBox, ActionListener listener) {
    46:     if (listener != null) {
    47:       comboBox.addActionListener (listener);
    48:     }
    49:     return comboBox;
    50:   }  //addListener(T extends JComboBox,ActionListener)
    51: 
    52:   //slider = addListener (slider, listener)
    53:   //  スライダーにチェンジリスナーを追加する
    54:   public static <T extends JSlider> T addListener (T slider, ChangeListener listener) {
    55:     if (listener != null) {
    56:       slider.addChangeListener (listener);
    57:     }
    58:     return slider;
    59:   }  //addListener(T extends JSlider,ActionListener)
    60: 
    61:   //spinner = addListener (spinner, listener)
    62:   //  スピナーにチェンジリスナーを追加する
    63:   public static <T extends JSpinner> T addListener (T spinner, ChangeListener listener) {
    64:     if (listener != null) {
    65:       spinner.addChangeListener (listener);
    66:     }
    67:     return spinner;
    68:   }  //addListener(T extends JSpinner,ChangeListener)
    69: 
    70:   //scrollList = addListener (scrollList, listener)
    71:   //  スクロールリストにリストセレクションリスナーを追加する
    72:   public static <T extends ScrollList> T addListener (T scrollList, ListSelectionListener listener) {
    73:     if (listener != null) {
    74:       scrollList.addListSelectionListener (listener);
    75:     }
    76:     return scrollList;
    77:   }  //addListener(T extends ScrollList,ListSelectionListener)
    78: 
    79:   //component = addListener (component, listener)
    80:   //  コンポーネントにフォーカスリスナーを追加する
    81:   public static <T extends Component> T addListener (T component, FocusListener listener) {
    82:     if (listener != null) {
    83:       component.addFocusListener (listener);
    84:     }
    85:     return component;
    86:   }  //addListener(T extends Component,FocusListener)
    87: 
    88:   //component = addListener (component, listener)
    89:   //  コンポーネントにキーリスナーを追加する
    90:   public static <T extends Component> T addListener (T component, KeyListener listener) {
    91:     if (listener != null) {
    92:       component.addKeyListener (listener);
    93:     }
    94:     return component;
    95:   }  //addListener(T extends Component,KeyListener)
    96: 
    97:   //component = addListener (component, listener)
    98:   //  コンポーネントにコンポーネントリスナーを追加する
    99:   public static <T extends Component> T addListener (T component, ComponentListener listener) {
   100:     if (listener != null) {
   101:       component.addComponentListener (listener);
   102:     }
   103:     return component;
   104:   }  //addListener(T extends Component,ComponentListener)
   105: 
   106:   //component = addListener (component, listener)
   107:   //  コンポーネントにマウスリスナー、マウスモーションリスナー、マウスホイールリスナーを追加する
   108:   public static <T extends Component> T addListener (T component, MouseAdapter listener) {
   109:     if (listener != null) {
   110:       component.addMouseListener (listener);
   111:       component.addMouseMotionListener (listener);
   112:       component.addMouseWheelListener (listener);
   113:     }
   114:     return component;
   115:   }  //addListener(T extends Component,MouseAdapter)
   116: 
   117:   //component = addListener (component, listener)
   118:   //  コンポーネントにマウスリスナーを追加する
   119:   public static <T extends Component> T addListener (T component, MouseListener listener) {
   120:     if (listener != null) {
   121:       component.addMouseListener (listener);
   122:     }
   123:     return component;
   124:   }  //addListener(T extends Component,MouseListener)
   125: 
   126:   //component = addListener (component, listener)
   127:   //  コンポーネントにマウスモーションリスナーを追加する
   128:   public static <T extends Component> T addListener (T component, MouseMotionListener listener) {
   129:     if (listener != null) {
   130:       component.addMouseMotionListener (listener);
   131:     }
   132:     return component;
   133:   }  //addListener(T extends Component,MouseMotionListener)
   134: 
   135:   //component = addListener (component, listener)
   136:   //  コンポーネントにマウスホイールリスナーを追加する
   137:   public static <T extends Component> T addListener (T component, MouseWheelListener listener) {
   138:     if (listener != null) {
   139:       component.addMouseWheelListener (listener);
   140:     }
   141:     return component;
   142:   }  //addListener(T extends Component,MouseWheelListener)
   143: 
   144:   //window = addListener (window, listener)
   145:   //  ウインドウにウインドウリスナー、ウインドウステートリスナー、ウインドウフォーカスリスナーを追加する
   146:   public static <T extends Window> T addListener (T window, WindowAdapter listener) {
   147:     if (listener != null) {
   148:       window.addWindowListener (listener);
   149:       window.addWindowStateListener (listener);
   150:       window.addWindowFocusListener (listener);
   151:     }
   152:     return window;
   153:   }  //addListener(T extends Window,WindowAdapter)
   154: 
   155:   //window = addListener (window, listener)
   156:   //  ウインドウにウインドウリスナーを追加する
   157:   public static <T extends Window> T addListener (T window, WindowListener listener) {
   158:     if (listener != null) {
   159:       window.addWindowListener (listener);
   160:     }
   161:     return window;
   162:   }  //addListener(T extends Window,WindowListener)
   163: 
   164:   //window = addListener (window, listener)
   165:   //  ウインドウにウインドウステートリスナーを追加する
   166:   public static <T extends Window> T addListener (T window, WindowStateListener listener) {
   167:     if (listener != null) {
   168:       window.addWindowStateListener (listener);
   169:     }
   170:     return window;
   171:   }  //addListener(T extends Window,WindowStateListener)
   172: 
   173:   //window = addListener (window, listener)
   174:   //  ウインドウにウインドウフォーカスリスナーを追加する
   175:   public static <T extends Window> T addListener (T window, WindowFocusListener listener) {
   176:     if (listener != null) {
   177:       window.addWindowFocusListener (listener);
   178:     }
   179:     return window;
   180:   }  //addListener(T extends Window,WindowFocusListener)
   181: 
   182:   //textComponent = addListener (textComponent, listener)
   183:   //  テキストコンポーネントにキャレットリスナーを追加する
   184:   public static <T extends JTextComponent> T addListener (T textComponent, CaretListener listener) {
   185:     if (listener != null) {
   186:       textComponent.addCaretListener (listener);
   187:     }
   188:     return textComponent;
   189:   }  //addListener(T extends JTextComponent,CaretListener)
   190: 
   191: 
   192:   //--------------------------------------------------------------------------------
   193:   //コンポーネントに属性を追加する
   194:   //  ジェネリクスを用いてパラメータのコンポーネントをクラスを変えずにそのまま返すメソッドを定義する
   195:   //  コンポーネントのインスタンスメソッドがコンポーネント自身を返してくれると、
   196:   //  メソッドチェーンが組めて括弧をネストする必要がなくなりコードが読みやすくなるのだが、
   197:   //  元のクラスのまま利用できなければ既存のメソッドの返却値をいちいちキャストしなければならず、
   198:   //  結局括弧が増えることになる
   199: 
   200:   //component = setToolTipText (component, toolTipText)
   201:   public static <T extends JComponent> T setToolTipText (T component, String toolTipText) {
   202:     component.setToolTipText (toolTipText);
   203:     return component;
   204:   }  //setToolTipText(T extends JComponent,String)
   205: 
   206:   //component = setName (component, name)
   207:   public static <T extends Component> T setName (T component, String name) {
   208:     component.setName (name);
   209:     return component;
   210:   }  //setName(T extends Component,String)
   211: 
   212:   //component = setVisible (component, visible)
   213:   public static <T extends Component> T setVisible (T component, boolean visible) {
   214:     component.setVisible (visible);
   215:     return component;
   216:   }  //setVisible(T extends Component,boolean)
   217: 
   218:   //component = setColor (component, foreground, background)
   219:   public static <T extends Component> T setColor (T component, Color foreground, Color background) {
   220:     component.setBackground (background);
   221:     component.setForeground (foreground);
   222:     return component;
   223:   }  //setColor(T extends Component,Color,Color)
   224: 
   225:   //component = setFont (component, font)
   226:   public static <T extends Component> T setFont (T component, Font font) {
   227:     component.setFont (font);
   228:     return component;
   229:   }  //setFont(T extends Component,Font)
   230: 
   231:   //component = bold (component)
   232:   //component = italic (component)
   233:   //component = boldItalic (component)
   234:   public static <T extends Component> T bold (T component) {
   235:     return setFont (component, component.getFont ().deriveFont (Font.BOLD));
   236:   }  //bold(T extends Component)
   237:   public static <T extends Component> T italic (T component) {
   238:     return setFont (component, component.getFont ().deriveFont (Font.ITALIC));
   239:   }  //italic(T extends Component)
   240:   public static <T extends Component> T boldItalic (T component) {
   241:     return setFont (component, component.getFont ().deriveFont (Font.BOLD | Font.ITALIC));
   242:   }  //boldItalic(T extends Component)
   243: 
   244:   //component = pointSize (component)
   245:   public static <T extends Component> T pointSize (T component, int size) {
   246:     return setFont (component, component.getFont ().deriveFont ((float) size));
   247:   }
   248: 
   249:   //component = setEnabled (component, enabled)
   250:   //  コンポーネントが有効かどうか指定する
   251:   public static <T extends Component> T setEnabled (T component, boolean enabled) {
   252:     component.setEnabled (enabled);
   253:     return component;
   254:   }  //setEnabled(T extends Component,boolean)
   255: 
   256:   //component = setMaximumSize (component, width, height)
   257:   //  コンポーネントの最大サイズを指定する
   258:   public static <T extends Component> T setMaximumSize (T component, int width, int height) {
   259:     component.setMaximumSize (new Dimension (width, height));
   260:     return component;
   261:   }  //setMaximumSize(T extends Component,int,int)
   262: 
   263:   //component = setMinimumSize (component, width, height)
   264:   //  コンポーネントの最小サイズを指定する
   265:   public static <T extends Component> T setMinimumSize (T component, int width, int height) {
   266:     component.setMinimumSize (new Dimension (width, height));
   267:     return component;
   268:   }  //setMinimumSize(T extends Component,int,int)
   269: 
   270:   //component = setPreferredSize (component, width, height)
   271:   //  コンポーネントの推奨サイズを指定する
   272:   public static <T extends Component> T setPreferredSize (T component, int width, int height) {
   273:     component.setPreferredSize (new Dimension (width, height));
   274:     return component;
   275:   }  //setPreferredSize(T extends Component,int,int)
   276: 
   277:   //component = setFixedSize (component, width, height)
   278:   //  コンポーネントの固定サイズを指定する
   279:   public static <T extends Component> T setFixedSize (T component, int width, int height) {
   280:     Dimension d = new Dimension (width, height);
   281:     component.setMinimumSize (d);
   282:     component.setMaximumSize (d);
   283:     component.setPreferredSize (d);
   284:     return component;
   285:   }  //setFixedSize(T extends Component,int,int)
   286: 
   287:   //component = setEmptyBorder (component, top, left, bottom, right)
   288:   //  コンポーネントに透過ボーダーを付ける
   289:   public static <T extends JComponent> T setEmptyBorder (T component, int top, int left, int bottom, int right) {
   290:     component.setBorder (new EmptyBorder (top, left, bottom, right));
   291:     return component;
   292:   }  //setEmptyBorder(T extends JComponent,int,int,int,int)
   293: 
   294:   //component = setLineBorder (component)
   295:   //  コンポーネントにラインボーダーを付ける
   296:   public static <T extends JComponent> T setLineBorder (T component) {
   297:     component.setBorder (new LineBorder (MetalLookAndFeel.getSeparatorForeground (), 1));  //primary1
   298:     return component;
   299:   }  //setLineBorder(T extends JComponent)
   300: 
   301:   //component = setTitledLineBorder (component, title)
   302:   //  コンポーネントにタイトル付きラインボーダーを付ける
   303:   public static <T extends JComponent> T setTitledLineBorder (T component, String title) {
   304:     component.setBorder (new TitledBorder (new LineBorder (MetalLookAndFeel.getSeparatorForeground (), 1), title));  //primary1
   305:     return component;
   306:   }  //setTitledLineBorder(T extends JComponent,String)
   307: 
   308:   //component = setEtchedBorder (component, title)
   309:   //  コンポーネントにエッチングボーダーを付ける
   310:   public static <T extends JComponent> T setEtchedBorder (T component) {
   311:     component.setBorder (new EtchedBorder (new Color (LnF.lnfRGB[10]), new Color (LnF.lnfRGB[14])));
   312:     return component;
   313:   }  //setEtchedBorder(T extends JComponent)
   314: 
   315:   //component = setTitledEtchedBorder (component, title)
   316:   //  コンポーネントにタイトル付きエッチングボーダーを付ける
   317:   public static <T extends JComponent> T setTitledEtchedBorder (T component, String title) {
   318:     component.setBorder (new TitledBorder (new EtchedBorder (), title));
   319:     return component;
   320:   }  //setTitledEtchedBorder(T extends JComponent,String)
   321: 
   322:   //parent = addComponents (parent, component, ...)
   323:   //  コンポーネントにコンポーネントを追加する
   324:   public static <T extends JComponent> T addComponents (T parent, Component... components) {
   325:     for (Component component : components) {
   326:       if (component != null) {
   327:         parent.add (component);
   328:       }
   329:     }
   330:     return parent;
   331:   }  //addComponents(T extends JComponent,Component...)
   332: 
   333:   //parent = removeComponents (parent, child, ...)
   334:   //  コンポーネントからコンポーネントを取り除く
   335:   public static <T extends JComponent> T removeComponents (T parent, Component... components) {
   336:     for (Component component : components) {
   337:       if (component != null) {
   338:         parent.remove (component);
   339:       }
   340:     }
   341:     return parent;
   342:   }  //removeComponents(T extends JComponent,Component...)
   343: 
   344:   //ボタン
   345: 
   346:   //button = setText (button, text)
   347:   public static <T extends AbstractButton> T setText (T button, String text) {
   348:     button.setText (text);
   349:     return button;
   350:   }  //setText(T extends AbstractButton,String)
   351: 
   352:   //button = setHorizontalAlignment (button, alignment)
   353:   //  SwingConstants.RIGHT
   354:   //  SwingConstants.LEFT
   355:   //  SwingConstants.CENTER (デフォルト)
   356:   //  SwingConstants.LEADING
   357:   //  SwingConstants.TRAILING
   358:   public static <T extends AbstractButton> T setHorizontalAlignment (T button, int alignment) {
   359:     button.setHorizontalAlignment (alignment);
   360:     return button;
   361:   }  //setHorizontalAlignment(T extends AbstractButton,int)
   362: 
   363:   //button = setVerticalAlignment (button, alignment)
   364:   //  SwingConstants.CENTER (デフォルト)
   365:   //  SwingConstants.TOP
   366:   //  SwingConstants.BOTTOM
   367:   public static <T extends AbstractButton> T setVerticalAlignment (T button, int alignment) {
   368:     button.setVerticalAlignment (alignment);
   369:     return button;
   370:   }  //setVerticalAlignment(T extends AbstractButton,int)
   371: 
   372:   //テキストフィールド
   373: 
   374:   //button = setHorizontalAlignment (textField, alignment)
   375:   //  JTextField.RIGHT
   376:   //  JTextField.LEFT (デフォルト)
   377:   //  JTextField.CENTER
   378:   //  JTextField.LEADING
   379:   //  JTextField.TRAILING
   380:   public static <T extends JTextField> T setHorizontalAlignment (T textField, int alignment) {
   381:     textField.setHorizontalAlignment (alignment);
   382:     return textField;
   383:   }  //setHorizontalAlignment(T extends JTextField,int)
   384: 
   385:   //テキストコンポーネント
   386: 
   387:   //component = setEditable (component, enabled)
   388:   //  コンポーネントが編集可能かどうか指定する
   389:   public static <T extends JTextComponent> T setEditable (T component, boolean enabled) {
   390:     component.setEditable (enabled);
   391:     return component;
   392:   }  //setEditable(T extends JTextComponent,boolean)
   393: 
   394: 
   395:   //--------------------------------------------------------------------------------
   396:   //フレームとダイアログを作る
   397:   //  ウインドウリスナー
   398:   //    ウインドウを開いたとき  activated,opened
   399:   //    フォーカスを失ったとき  deactivated
   400:   //    フォーカスを取得したとき  activated
   401:   //    ウインドウをアイコン化したとき  iconified,[deactivated]
   402:   //    ウインドウを元のサイズに戻したとき  deiconified,activated
   403:   //    ウインドウを閉じたとき  closing,[deactivated],closed
   404: 
   405:   //frame = createFrame (title, mnbMenuBar, component)
   406:   //  フレームを作る
   407:   //  すぐに開く
   408:   //  デフォルトのクローズボタンの動作はEXIT_ON_CLOSE
   409:   //  クローズボタンがクリックされたとき後始末を行なってから終了するとき
   410:   //    frame = createFrame (title, mnbMenuBar, component);
   411:   //    frame.setDefaultCloseOperation (WindowConstants.DISPOSE_ON_CLOSE);
   412:   //    frame.addWindowListener (new WindowAdapter () {
   413:   //      @Override public void windowClosed (WindowEvent we) {
   414:   //        後始末;
   415:   //        System.exit (0);
   416:   //      }
   417:   //    });
   418:   public static JFrame createFrame (String title, JMenuBar mnbMenuBar, JComponent component) {
   419:     JFrame frame = new JFrame (title);
   420:     frame.setUndecorated (true);  //ウインドウの枠を消す
   421:     frame.getRootPane().setWindowDecorationStyle (JRootPane.FRAME);  //飾り枠を描く
   422:     //frame.setLocationByPlatform (true);
   423:     frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
   424:     if (mnbMenuBar != null) {
   425:       frame.setJMenuBar (mnbMenuBar);
   426:     }
   427:     //frame.getContentPane ().add (component, BorderLayout.CENTER);
   428:     component.setOpaque (true);
   429:     frame.setContentPane (component);
   430:     frame.pack ();
   431:     frame.setVisible (true);
   432:     return frame;
   433:   }  //createFrame(String,JMenuBar,JComponent)
   434: 
   435:   public static JFrame createSubFrame (String title, JMenuBar mnbMenuBar, JComponent component) {
   436:     JFrame frame = new JFrame (title);
   437:     frame.setUndecorated (true);  //ウインドウの枠を消す
   438:     frame.getRootPane().setWindowDecorationStyle (JRootPane.FRAME);  //飾り枠を描く
   439:     frame.setLocationByPlatform (true);
   440:     frame.setDefaultCloseOperation (JFrame.HIDE_ON_CLOSE);
   441:     if (mnbMenuBar != null) {
   442:       frame.setJMenuBar (mnbMenuBar);
   443:     }
   444:     //frame.getContentPane ().add (component, BorderLayout.CENTER);
   445:     component.setOpaque (true);
   446:     frame.setContentPane (component);
   447:     frame.pack ();
   448:     return frame;
   449:   }  //createSubFrame(String,JMenuBar,JComponent)
   450: 
   451:   public static JFrame createRestorableFrame (String key, String title, JMenuBar mnbMenuBar, JComponent component) {
   452:     JFrame frame = new RestorableFrame (key, title);
   453:     frame.setUndecorated (true);  //ウインドウの枠を消す
   454:     frame.getRootPane().setWindowDecorationStyle (JRootPane.FRAME);  //飾り枠を描く
   455:     //frame.setLocationByPlatform (true);
   456:     frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
   457:     if (mnbMenuBar != null) {
   458:       frame.setJMenuBar (mnbMenuBar);
   459:     }
   460:     //frame.getContentPane ().add (component, BorderLayout.CENTER);
   461:     component.setOpaque (true);
   462:     frame.setContentPane (component);
   463:     frame.pack ();
   464:     frame.setVisible (true);
   465:     return frame;
   466:   }  //createRestorableFrame(String,String,JMenuBar,JComponent)
   467: 
   468:   public static JFrame createRestorableSubFrame (String key, String title, JMenuBar mnbMenuBar, JComponent component) {
   469:     return createRestorableSubFrame (key, title, mnbMenuBar, component, true);
   470:   }
   471:   public static JFrame createRestorableSubFrame (String key, String title, JMenuBar mnbMenuBar, JComponent component, boolean resizable) {
   472:     JFrame frame = new RestorableFrame (key, title, resizable);
   473:     frame.setUndecorated (true);  //ウインドウの枠を消す
   474:     frame.getRootPane().setWindowDecorationStyle (JRootPane.FRAME);  //飾り枠を描く
   475:     //frame.setLocationByPlatform (true);
   476:     frame.setDefaultCloseOperation (JFrame.HIDE_ON_CLOSE);
   477:     if (mnbMenuBar != null) {
   478:       frame.setJMenuBar (mnbMenuBar);
   479:     }
   480:     //frame.getContentPane ().add (component, BorderLayout.CENTER);
   481:     component.setOpaque (true);
   482:     frame.setContentPane (component);
   483:     frame.setResizable (resizable);
   484:     frame.pack ();
   485:     return frame;
   486:   }  //createRestorableSubFrame(String,String,JMenuBar,JComponent)
   487: 
   488:   //dialog = createModalDialog (owner, title, component)
   489:   //dialog = createModelessDialog (owner, title, component)
   490:   //dialog = createDialog (owner, title, component, modal)
   491:   //  ダイアログを作る(ownerを指定する)
   492:   //  まだ開かない
   493:   //  デフォルトのクローズボタンの動作はHIDE_ON_CLOSE
   494:   //  閉じてもdialog.setVisible(true)で再表示できる
   495:   public static JDialog createModalDialog (Frame owner, String title, JComponent component) {
   496:     return createDialog (owner, title, true, component);
   497:   }  //createModalDialog(Frame,String,JComponent)
   498:   public static JDialog createModelessDialog (Frame owner, String title, JComponent component) {
   499:     return createDialog (owner, title, false, component);
   500:   }  //createModelessDialog(Frame,String,JComponent)
   501:   public static JDialog createDialog (Frame owner, String title, boolean modal, JComponent component) {
   502:     JDialog dialog = new JDialog (owner, title, modal);
   503:     dialog.setUndecorated (true);  //ウインドウの枠を消す
   504:     dialog.getRootPane ().setWindowDecorationStyle (JRootPane.FRAME);  //飾り枠を描く
   505:     dialog.setAlwaysOnTop (modal);  //モーダルのときは常に手前に表示、モードレスのときは奥に移動できる
   506:     dialog.setLocationByPlatform (true);
   507:     dialog.setDefaultCloseOperation (WindowConstants.HIDE_ON_CLOSE);
   508:     dialog.getContentPane ().add (component, BorderLayout.CENTER);
   509:     dialog.pack ();
   510:     dialog.setVisible (false);
   511:     return dialog;
   512:   }  //createDialog(Frame,String,boolean,JComponent)
   513: 
   514: 
   515:   //--------------------------------------------------------------------------------
   516:   //パネルを作る
   517: 
   518:   //box = createHorizontalBox (component, ...)
   519:   //  コンポーネントを横に並べるボックスを作る
   520:   public static Box createHorizontalBox (Component... components) {
   521:     return addComponents (Box.createHorizontalBox (), components);
   522:   }  //createHorizontalBox(Component...)
   523: 
   524:   //box = createVerticalBox (component, ...)
   525:   //  コンポーネントを縦に並べるボックスを作る
   526:   public static Box createVerticalBox (Component... components) {
   527:     return addComponents (Box.createVerticalBox (), components);
   528:   }  //createVerticalBox(Component...)
   529: 
   530:   //box = createGlueBox (component)
   531:   //box = createGlueBox (orientation, component)
   532:   //  コンポーネントを引き伸ばさず指定された方向に寄せて表示する
   533:   //  component自身がmaximumSizeを持っていること
   534:   //  componentがBorderLayoutでCENTERがmaximumSizeを持っているのではダメ
   535:   //  orientation
   536:   //    SwingConstants.NORTH_WEST SwingConstants.NORTH  SwingConstants.NORTH_EAST
   537:   //    SwingConstants.WEST       SwingConstants.CENTER SwingConstants.EAST
   538:   //    SwingConstants.SOUTH_WEST SwingConstants.SOUTH  SwingConstants.SOUTH_EAST
   539:   public static Box createGlueBox (JComponent component) {
   540:     return createGlueBox (SwingConstants.CENTER, component);
   541:   }  //createGlueBox(JComponent)
   542:   public static Box createGlueBox (int orientation, JComponent component) {
   543:     Box box = (orientation == SwingConstants.NORTH_WEST ||
   544:                orientation == SwingConstants.WEST ||
   545:                orientation == SwingConstants.SOUTH_WEST ?
   546:                createHorizontalBox (component, Box.createHorizontalGlue ()) :
   547:                orientation == SwingConstants.NORTH_EAST ||
   548:                orientation == SwingConstants.EAST ||
   549:                orientation == SwingConstants.SOUTH_EAST ?
   550:                createHorizontalBox (Box.createHorizontalGlue (), component) :
   551:                createHorizontalBox (Box.createHorizontalGlue (), component, Box.createHorizontalGlue ()));
   552:     return (orientation == SwingConstants.NORTH_WEST ||
   553:             orientation == SwingConstants.NORTH ||
   554:             orientation == SwingConstants.NORTH_EAST ?
   555:             createVerticalBox (box, Box.createVerticalGlue ()) :
   556:             orientation == SwingConstants.SOUTH_WEST ||
   557:             orientation == SwingConstants.SOUTH ||
   558:             orientation == SwingConstants.SOUTH_EAST ?
   559:             createVerticalBox (Box.createVerticalGlue (), box) :
   560:             createVerticalBox (Box.createVerticalGlue (), box, Box.createVerticalGlue ()));
   561:   }  //createGlueBox(int,JComponent)
   562: 
   563:   //panel = createFlowPanel (component, ...)
   564:   //panel = createFlowPanel (align, component, ...)
   565:   //panel = createFlowPanel (hgap ,vgap, component, ...)
   566:   //panel = createFlowPanel (align, hgap, vgap, component, ...)
   567:   //  FlowLayoutのパネルを作る
   568:   //  align
   569:   //    FlowLayout.CENTER  中央揃え
   570:   //    FlowLayout.LEFT    左揃え
   571:   //    FlowLayout.RIGHT   右揃え
   572:   public static JPanel createFlowPanel (Component... components) {
   573:     return createFlowPanel (FlowLayout.LEFT, 0, 0, components);
   574:   }  //createFlowPanel(Component...)
   575:   public static JPanel createFlowPanel (int align, Component... components) {
   576:     return createFlowPanel (align, 0, 0, components);
   577:   }  //createFlowPanel(int,Component...)
   578:   public static JPanel createFlowPanel (int hgap, int vgap, Component... components) {
   579:     return createFlowPanel (FlowLayout.LEFT, hgap, vgap, components);
   580:   }  //createFlowPanel(int,int,Component...)
   581:   public static JPanel createFlowPanel (int align, int hgap, int vgap, Component... components) {
   582:     JPanel panel = new JPanel (new FlowLayout (align, hgap, vgap));
   583:     panel.setOpaque (true);
   584:     return addComponents (panel, components);
   585:   }  //createFlowPanel(int,int,int,Component...)
   586: 
   587:   //panel = createBorderPanel (component, ...)
   588:   //panel = createBorderPanel (hgap, vgap, component, ...)
   589:   //  BorderLayoutのパネルを作る
   590:   //  コンポーネントをCENTER,NORTH,WEST,SOUTH,EASTの順序で指定する
   591:   //  末尾のコンポーネントを省略するか途中のコンポーネントにnullを指定するとその部分は設定されない
   592:   public static JPanel createBorderPanel (JComponent... components) {
   593:     return createBorderPanel (0, 0, components);
   594:   }  //createBorderPanel(JComponent...)
   595:   public static JPanel createBorderPanel (int hgap, int vgap, JComponent... components) {
   596:     JPanel panel = new JPanel (new BorderLayout (hgap, vgap));
   597:     panel.setOpaque (true);
   598:     if (components.length >= 1) {
   599:       if (components[0] != null) {
   600:         panel.add (components[0], BorderLayout.CENTER);
   601:       }
   602:       if (components.length >= 2) {
   603:         if (components[1] != null) {
   604:           panel.add (components[1], BorderLayout.NORTH);
   605:         }
   606:         if (components.length >= 3) {
   607:           if (components[2] != null) {
   608:             panel.add (components[2], BorderLayout.WEST);
   609:           }
   610:           if (components.length >= 4) {
   611:             if (components[3] != null) {
   612:               panel.add (components[3], BorderLayout.SOUTH);
   613:             }
   614:             if (components.length >= 5 && components[4] != null) {
   615:               panel.add (components[4], BorderLayout.EAST);
   616:             }
   617:           }
   618:         }
   619:       }
   620:     }
   621:     return panel;
   622:   }  //createBorderPanel(int,int,JComponent...)
   623: 
   624:   //panel = createGridPanel (colCount, rowCount, gridStyles, colStyless, rowStyless, cellStyless, objectArray, ...)
   625:   //  GridBagLayoutのパネルを作る
   626:   //    colCount          列数
   627:   //    rowCount          行数
   628:   //    gridStyles        すべてのセルの共通のスタイル
   629:   //    colStyles         列毎の共通のスタイル。列の区切りは";"。スタイルの区切りは","
   630:   //    rowStyles         行毎の共通のスタイル。行の区切りは";"。スタイルの区切りは","
   631:   //    cellStyles        個々のセルのスタイル。セルの区切りは";"。スタイルの区切りは","。上または左のセルが重なっているセルは含まない
   632:   //                      colSpan        列数
   633:   //                      rowSpan        行数
   634:   //                      width          幅
   635:   //                      height         高さ
   636:   //                      widen          幅をいっぱいまで伸ばす
   637:   //                      lengthen       高さをいっぱいまで伸ばす
   638:   //                      center         左右に寄せない
   639:   //                      left           左に寄せる
   640:   //                      right          右に寄せる
   641:   //                      middle         上下に寄せない
   642:   //                      top            上に寄せる
   643:   //                      bottom         下に寄せる
   644:   //                      paddingTop     上端のパディング
   645:   //                      paddingRight   右端のパディング
   646:   //                      paddingBottom  下端のパディング
   647:   //                      paddingLeft    左端のパディング
   648:   //                      bold           ボールド
   649:   //                      italic         イタリック
   650:   //    objectArray, ...  セルに表示するオブジェクトの配列。長さが列数×行数よりも少ないときは上または左のセルが重なっているセルが詰められていると判断される。このときcellStylesも詰められたインデックスで参照される
   651:   //  gridStyles;colStyles;rowStyles;cellStylesの順序で個々のセルに対応するスタイルが連結される
   652:   //  同時に指定できないスタイルは後から指定した方が優先される
   653:   public static JPanel createGridPanel (int colCount, int rowCount, String gridStyles, String colStyless, String rowStyless, String cellStyless, Object... objectArray) {
   654:     String[] colStylesArray = (colStyless != null ? colStyless : "").split (";");
   655:     String[] rowStylesArray = (rowStyless != null ? rowStyless : "").split (";");
   656:     String[] cellStylesArray = (cellStyless != null ? cellStyless : "").split (";");
   657:     int cellCount = colCount * rowCount;
   658:     //Component[] componentArray = new Component[cellCount];  //セルのオブジェクト。上または左のセルが重なっているセルは含まない
   659:     boolean[] cellFilledArray = new boolean[cellCount];  //セルが充填済みかどうか。colCount*rowCountのセルをすべて含む
   660:     GridBagLayout gridbag = new GridBagLayout ();
   661:     JPanel panel = new JPanel (gridbag);
   662:     GridBagConstraints c = new GridBagConstraints ();
   663:     int objectIndex = 0;  //objectArrayとcellStylesArrayの詰められたインデックス
   664:     boolean objectClosed = objectArray.length < cellCount;  //objectArrayとcellStylesArrayが詰められている(上または左のセルが重なっているセルを含まない)。objectArray[objectClosed?objectIndex:cellIndex]
   665:     for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
   666:       for (int colIndex = 0; colIndex < colCount; colIndex++) {
   667:         int cellIndex = colIndex + colCount * rowIndex;  //セルのインデックス。colCount*rowCountのセルをすべて含む
   668:         if (cellFilledArray[cellIndex]) {  //充填済み
   669:           continue;
   670:         }
   671:         int colSpan = 1;
   672:         int rowSpan = 1;
   673:         int width = 1;
   674:         int height = 1;
   675:         int fill = 0;  //1=widen,2=lengthen
   676:         int anchor = 0;  //1=left,2=right,4=top,8=bottom
   677:         int paddingTop = 0;
   678:         int paddingRight = 0;
   679:         int paddingBottom = 0;
   680:         int paddingLeft = 0;
   681:         int fontStyle = 0;  //1=bold,2=italic
   682:         for (String style : ((gridStyles != null ? gridStyles : "") + "," +
   683:                              (colIndex < colStylesArray.length ? colStylesArray[colIndex] : "") + "," +
   684:                              (rowIndex < rowStylesArray.length ? rowStylesArray[rowIndex] : "") + "," +
   685:                              ((objectClosed ? objectIndex : cellIndex) < cellStylesArray.length ? cellStylesArray[objectClosed ? objectIndex : cellIndex] : "")).split (",")) {
   686:           String[] keyValue = style.split ("=");
   687:           String key = keyValue.length < 1 ? "" : keyValue[0].trim ();
   688:           int value = keyValue.length < 2 ? 1 : Integer.parseInt (keyValue[1]);
   689:           switch (key) {
   690:           case "colSpan":  //列数
   691:             colSpan = value;
   692:             break;
   693:           case "rowSpan":  //行数
   694:             rowSpan = value;
   695:             break;
   696:           case "width":  //幅
   697:             width = value;
   698:             break;
   699:           case "height":  //高さ
   700:             height = value;
   701:             break;
   702:           case "widen":  //幅をいっぱいまで伸ばす
   703:             fill |= 1;
   704:             break;
   705:           case "lengthen":  //高さをいっぱいまで伸ばす
   706:             fill |= 2;
   707:             break;
   708:           case "center":  //左右に寄せない
   709:             anchor &= ~0b0011;
   710:             break;
   711:           case "left":  //左に寄せる
   712:             anchor = anchor & ~0b0011 | 0b0001;
   713:             break;
   714:           case "right":  //右に寄せる
   715:             anchor = anchor & ~0b0011 | 0b0010;
   716:             break;
   717:           case "middle":  //上下に寄せない
   718:             anchor &= ~0b1100;
   719:             break;
   720:           case "top":  //上に寄せる
   721:             anchor = anchor & ~0b1100 | 0b0100;
   722:             break;
   723:           case "bottom":  //下に寄せる
   724:             anchor = anchor & ~0b1100 | 0b1000;
   725:             break;
   726:           case "paddingTop":  //上端のパディング
   727:             paddingTop = value;
   728:             break;
   729:           case "paddingRight":  //右端のパディング
   730:             paddingRight = value;
   731:             break;
   732:           case "paddingBottom":  //下端のパディング
   733:             paddingBottom = value;
   734:             break;
   735:           case "paddingLeft":  //左端のパディング
   736:             paddingLeft = value;
   737:             break;
   738:           case "bold":  //ボールド
   739:             fontStyle |= 1;
   740:             break;
   741:           case "italic":  //イタリック
   742:             fontStyle |= 2;
   743:             break;
   744:           }
   745:         }
   746:         c.gridx = colIndex;
   747:         c.gridy = rowIndex;
   748:         c.gridwidth = colSpan;
   749:         c.gridheight = rowSpan;
   750:         c.weightx = 0.0;
   751:         c.weighty = 0.0;
   752:         c.fill = (fill == 1 ? GridBagConstraints.HORIZONTAL :
   753:                   fill == 2 ? GridBagConstraints.VERTICAL :
   754:                   fill == 3 ? GridBagConstraints.BOTH :
   755:                   GridBagConstraints.NONE);
   756:         c.anchor = (anchor == 0b0001 ? GridBagConstraints.WEST :
   757:                     anchor == 0b0010 ? GridBagConstraints.EAST :
   758:                     anchor == 0b0100 ? GridBagConstraints.NORTH :
   759:                     anchor == 0b1000 ? GridBagConstraints.SOUTH :
   760:                     anchor == 0b0101 ? GridBagConstraints.NORTHWEST :
   761:                     anchor == 0b0110 ? GridBagConstraints.NORTHEAST :
   762:                     anchor == 0b1001 ? GridBagConstraints.SOUTHWEST :
   763:                     anchor == 0b1010 ? GridBagConstraints.SOUTHEAST :
   764:                     GridBagConstraints.CENTER);
   765:         c.insets = new Insets (paddingTop, paddingLeft, paddingBottom, paddingRight);
   766:         Object object = (objectClosed ? objectIndex : cellIndex) < objectArray.length ? objectArray[objectClosed ? objectIndex : cellIndex] : null;
   767:         Component component;
   768:         if (object == null) {
   769:           component = new JPanel ();
   770:         } else if (object instanceof String) {
   771:           String string = (String) object;
   772:           component = string.startsWith ("http://") || string.startsWith ("https://") ? createAnchor (string, string) : createLabel ((String) object);
   773:         } else if (object instanceof Component) {
   774:           component = (Component) object;
   775:         } else {
   776:           component = new JPanel ();
   777:         }
   778:         if (component instanceof JLabel) {
   779:           JLabel label = (JLabel) component;
   780:           if (fontStyle == 1) {
   781:             bold (label);
   782:           } else if (fontStyle == 2) {
   783:             italic (label);
   784:           } else if (fontStyle == 3) {
   785:             boldItalic (label);
   786:           }
   787:         }
   788: 
   789:         component.setMinimumSize (new Dimension (width, height));
   790:         if (width > 1 || height > 1) {
   791:           component.setPreferredSize (new Dimension (width, height));
   792:         }
   793:         gridbag.setConstraints (component, c);
   794:         panel.add (component);
   795:         //componentArray[objectIndex] = component;
   796:         for (int y = 0; y < rowSpan; y++) {
   797:           for (int x = 0; x < colSpan; x++) {
   798:             cellFilledArray[(colIndex + x) + colCount * (rowIndex + y)] = true;
   799:           }
   800:         }
   801: 
   802:         objectIndex++;
   803:       }  //for colIndex
   804:     }  //for rowIndex
   805:     return panel;
   806:   }  //createGridPanel(int,int,String,String,String,String,Object...)
   807: 
   808:   //scrollPane = createScrollPane (view)
   809:   //scrollPane = createScrollPane (view, vsbPolicy, hsbPolicy)
   810:   //  スクロールペインを作る
   811:   //  推奨サイズが必要なので通常はsetPreferredSize (createScrollPane (view), width, height)の形式で作る
   812:   //  vsbPolicy
   813:   //    ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED
   814:   //    ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER
   815:   //    ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS
   816:   //  hsbPolicy
   817:   //    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED
   818:   //    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
   819:   //    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS
   820:   public static JScrollPane createScrollPane (Component view) {
   821:     return createScrollPane (view,
   822:                              ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
   823:                              ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
   824:   }  //createScrollPane(Component)
   825:   public static JScrollPane createScrollPane (Component view, int vsbPolicy, int hsbPolicy) {
   826:     return new JScrollPane (view, vsbPolicy, hsbPolicy);
   827:   }  //createScrollPane(Component,int,int)
   828: 
   829:   //splitPane = createHorizontalSplitPane (component, ...)
   830:   //splitPane = createVerticalSplitPane (component, ...)
   831:   //splitPane = createSplitPane (orientation, component, ...)
   832:   //  スプリットペインを作る
   833:   //  orientation
   834:   //    JSplitPane.HORIZONTAL_SPLIT
   835:   //    JSplitPane.VERTICAL_SPLIT
   836:   public static JSplitPane createHorizontalSplitPane (Component... components) {
   837:     return createSplitPane (JSplitPane.HORIZONTAL_SPLIT, components);
   838:   }  //createHorizontalSplitPane(Component...)
   839:   public static JSplitPane createVerticalSplitPane (Component... components) {
   840:     return createSplitPane (JSplitPane.VERTICAL_SPLIT, components);
   841:   }  //createVerticalSplitPane(Component...)
   842:   public static JSplitPane createSplitPane (int orientation, Component... components) {
   843:     JSplitPane splitPane = new JSplitPane (orientation, true, components[0], components[1]);
   844:     for (int i = 2; i < components.length; i++) {
   845:       splitPane = new JSplitPane (orientation, true, splitPane, components[i]);  //((0,1),2)...
   846:     }
   847:     return splitPane;
   848:   }  //createSplitPane(int,Component...)
   849: 
   850: 
   851:   //--------------------------------------------------------------------------------
   852:   //セパレータを作る
   853: 
   854:   //separator = createHorizontalSeparator ()
   855:   //separator = createVerticalSeparator ()
   856:   //  セパレータを作る
   857:   public static JSeparator createHorizontalSeparator () {
   858:     return new JSeparator (SwingConstants.HORIZONTAL);
   859:   }  //createHorizontalSeparator()
   860:   public static JSeparator createVerticalSeparator () {
   861:     return new JSeparator (SwingConstants.VERTICAL);
   862:   }  //createVerticalSeparator()
   863: 
   864: 
   865:   //--------------------------------------------------------------------------------
   866:   //ラベルを作る
   867: 
   868:   //label = createLabel (enText)
   869:   //label = createLabel (enText, alignment)
   870:   //  ラベルを作る
   871:   public static JLabel createLabel (String enText) {
   872:     return createLabel (enText, SwingConstants.CENTER);
   873:   }  //createLabel(String)
   874:   public static JLabel createLabel (String enText, int alignment) {
   875:     JLabel label = new JLabel (enText);
   876:     label.setForeground (MetalLookAndFeel.getBlack ());  //black
   877:     if (alignment == SwingConstants.NORTH_WEST ||
   878:         alignment == SwingConstants.NORTH ||
   879:         alignment == SwingConstants.NORTH_EAST ||
   880:         alignment == SwingConstants.TOP) {
   881:       label.setVerticalAlignment (SwingConstants.TOP);
   882:     } else if (alignment == SwingConstants.SOUTH_WEST ||
   883:         alignment == SwingConstants.SOUTH ||
   884:         alignment == SwingConstants.SOUTH_EAST ||
   885:         alignment == SwingConstants.BOTTOM) {
   886:       label.setVerticalAlignment (SwingConstants.BOTTOM);
   887:     } else if (alignment == SwingConstants.CENTER) {
   888:       label.setVerticalAlignment (SwingConstants.CENTER);
   889:     }
   890:     if (alignment == SwingConstants.NORTH_WEST ||
   891:         alignment == SwingConstants.WEST ||
   892:         alignment == SwingConstants.SOUTH_WEST ||
   893:         alignment == SwingConstants.LEFT) {
   894:       label.setHorizontalAlignment (SwingConstants.LEFT);
   895:     } else if (alignment == SwingConstants.NORTH_EAST ||
   896:         alignment == SwingConstants.EAST ||
   897:         alignment == SwingConstants.SOUTH_EAST ||
   898:         alignment == SwingConstants.RIGHT) {
   899:       label.setHorizontalAlignment (SwingConstants.RIGHT);
   900:     } else if (alignment == SwingConstants.CENTER) {
   901:       label.setHorizontalAlignment (SwingConstants.CENTER);
   902:     }
   903:     return label;
   904:   }  //createLabel(String,int)
   905: 
   906:   //label = createIconLabel (image)
   907:   //  アイコンラベルを作る
   908:   public static JLabel createIconLabel (Image image) {
   909:     JLabel label = new JLabel (new ImageIcon (image));
   910:     label.setBorder (new EmptyBorder (1, 1, 1, 1));  //アイコンボタンと同じサイズにする
   911:     return label;
   912:   }  //createIconLabel(Image)
   913: 
   914: 
   915:   //--------------------------------------------------------------------------------
   916:   //アンカーを作る
   917:   //  下線付きラベル
   918:   //  マウスカーソルは手の形
   919:   //  クリックされたらあらかじめ設定されたURIをブラウザに渡す
   920: 
   921:   //label = createAnchor (enText, uri)
   922:   //  アンカーを作る
   923:   public static boolean isObsoleteURI (String uri) {
   924:     return uri.startsWith ("http://www.nifty.ne.jp/forum/");  //"fsharp/"。リンク先が存在しないURI
   925:   }  //isObsoleteURI(String)
   926:   public static JLabel createAnchor (String enText, String uri) {
   927:     JLabel label = new UnderlinedLabel (enText);  //下線付きラベル
   928:     label.setForeground (MetalLookAndFeel.getBlack ());  //black
   929:     if (uri != null) {
   930:       if (isObsoleteURI (uri)) {
   931:         uri = "https://web.archive.org/web/" + "*" + "/" + uri;
   932:       }
   933:       label.setCursor (Cursor.getPredefinedCursor (Cursor.HAND_CURSOR));  //マウスカーソルは手の形
   934:       label.setToolTipText (uri);
   935:       label.addMouseListener (new AnchorAdapter (uri));  //クリックされたらあらかじめ設定されたURIをブラウザに渡す
   936:     }
   937:     return label;
   938:   }  //createAnchor(String,String)
   939: 
   940: 
   941:   //--------------------------------------------------------------------------------
   942:   //テキストフィールドを作る
   943: 
   944:   //textField = createTextField (text, columns)
   945:   //  テキストフィールドを作る
   946:   public static JTextField createTextField (String text, int columns) {
   947:     JTextField textField = new JTextField (text, columns);
   948:     textField.setForeground (new Color (LnF.lnfRGB[14]));
   949:     textField.setSelectionColor (new Color (LnF.lnfRGB[7]));  //選択領域の背景の色
   950:     //textField.setSelectedTextColor (new Color (LnF.lnfRGB[14]));  //選択領域のテキストの色
   951:     return textField;
   952:   }  //createTextField(String,int)
   953: 
   954:   //textField = createNumberField (text, columns)
   955:   //  数値入力用のテキストフィールドを作る
   956:   public static JTextField createNumberField (String text, int columns) {
   957:     return setHorizontalAlignment (
   958:       setFixedSize (
   959:         //setFont (
   960:         //  new JTextField (text),  //columnを指定すると幅を調節できなくなる
   961:         //  LnF.lnfMonospacedFont),
   962:         //10 + (LnF.lnfFontSize / 2) * columns, LnF.lnfFontSize + 4
   963:         new JTextField (text),  //columnを指定すると幅を調節できなくなる
   964:         10 + (LnF.lnfFontSize * 2 / 3) * columns, LnF.lnfFontSize + 4
   965:         ),
   966:       JTextField.RIGHT);
   967:   }  //createNumberField(int,int)
   968: 
   969: 
   970:   //--------------------------------------------------------------------------------
   971:   //スクロールテキストエリアを作る
   972: 
   973:   //scrollTextArea = createScrollTextArea (text, width, height)
   974:   //scrollTextArea = createScrollTextArea (text, width, height, editable)
   975:   //  スクロールテキストエリアを作る
   976:   public static ScrollTextArea createScrollTextArea (String text, int width, int height) {
   977:     return createScrollTextArea (text, width, height, false);
   978:   }  //createScrollTextArea(String,int,int)
   979:   public static ScrollTextArea createScrollTextArea (String text, int width, int height, boolean editable) {
   980:     ScrollTextArea scrollTextArea = setPreferredSize (
   981:       setFont (new ScrollTextArea (), LnF.lnfMonospacedFont),
   982:       width, height);
   983:     setEmptyBorder (scrollTextArea, 0, 0, 0, 0);
   984:     scrollTextArea.setMargin (new Insets (2, 4, 2, 4));  //グリッドを更新させるためJTextAreaではなくScrollTextAreaに設定する必要がある
   985:     JTextArea textArea = scrollTextArea.getTextArea ();
   986:     textArea.setEditable (editable);
   987:     scrollTextArea.setText (text);
   988:     scrollTextArea.setCaretPosition (0);
   989:     return scrollTextArea;
   990:   }  //createScrollTextArea(String,int,int,boolean)
   991: 
   992: 
   993:   //--------------------------------------------------------------------------------
   994:   //スクロールテキストペインを作る
   995: 
   996:   //scrollTextPane = createScrollTextPane (text, width, height)
   997:   //  スクロールテキストペインを作る
   998:   //  http://~の部分がハイパーリンクになる
   999:   //    許諾条件.txtの中に"(http://www.nifty.ne.jp/forum/fsharp/)"という部分がある
  1000:   //    ')'はURIに使える文字なので正しい方法では分離することができない
  1001:   //    ここではhttp://の直前に'('があるときは')'をURIに使えない文字とみなすことにする
  1002:   public static JScrollPane createScrollTextPane (String text, int width, int height) {
  1003:     JTextPane textPane = new JTextPane ();
  1004:     StyledDocument document = textPane.getStyledDocument ();
  1005:     Style defaultStyle = document.addStyle ("default", StyleContext.getDefaultStyleContext ().getStyle (StyleContext.DEFAULT_STYLE));
  1006:     int anchorNumber = 0;
  1007:     //  http://user:passwd@host:port/path?query#hash → http://host/path?query
  1008:     //Matcher matcher = Pattern.compile ("\\bhttps?://[-.0-9A-Za-z]*(?:/(?:[!$&-;=?-Z_a-z~]|%[0-9A-Fa-f]{2})*)?").matcher (text);
  1009:     Matcher matcher = Pattern.compile ("\\b" +
  1010:                                        "(?:" +
  1011:                                        "(?<!\\()https?://[-.0-9A-Za-z]*(?:/(?:[!$&-;=?-Z_a-z~]|%[0-9A-Fa-f]{2})*)?" +
  1012:                                        "|" +
  1013:                                        "(?<=\\()https?://[-.0-9A-Za-z]*(?:/(?:[!$&-(*-;=?-Z_a-z~]|%[0-9A-Fa-f]{2})*)?" +
  1014:                                        ")").matcher (text);
  1015:     try {
  1016:       int start = 0;
  1017:       while (matcher.find ()) {
  1018:         int end = matcher.start ();  //ハイパーリンクの開始位置
  1019:         if (start < end) {
  1020:           document.insertString (document.getLength (), text.substring (start, end), defaultStyle);  //ハイパーリンクの手前のテキスト
  1021:         }
  1022:         String anchorHref = matcher.group ();  //ハイパーリンク
  1023:         Style anchorStyle = document.addStyle ("anchor" + anchorNumber++, defaultStyle);
  1024:         JLabel anchorLabel = createAnchor (anchorHref, anchorHref);
  1025:         Dimension anchorSize = anchorLabel.getPreferredSize ();
  1026:         anchorLabel.setAlignmentY ((float) anchorLabel.getBaseline (anchorSize.width, anchorSize.height) / (float) anchorSize.height);  //JLabelのベースラインをテキストに合わせる
  1027:         StyleConstants.setComponent (anchorStyle, anchorLabel);
  1028:         document.insertString (document.getLength (), anchorHref, anchorStyle);
  1029:         start = matcher.end ();  //ハイパーリンクの終了位置
  1030:       }
  1031:       document.insertString (document.getLength (), text.substring (start), defaultStyle);  //残りのテキスト
  1032:     } catch (BadLocationException ble) {
  1033:     }
  1034:     textPane.setMargin (new Insets (2, 4, 2, 4));
  1035:     textPane.setEditable (false);
  1036:     textPane.setCaretPosition (0);
  1037:     JScrollPane scrollPane = new JScrollPane (textPane);
  1038:     scrollPane.setPreferredSize (new Dimension (width, height));
  1039:     return scrollPane;
  1040:   }  //createScrollTextPane(String,int,int)
  1041: 
  1042: 
  1043:   //--------------------------------------------------------------------------------
  1044:   //ボタンを作る
  1045: 
  1046:   //button = createButton (enText, listener)
  1047:   //button = createButton (enText, mnemonic, listener)
  1048:   //  テキストのボタンを作る
  1049:   public static JButton createButton (String enText, ActionListener listener) {
  1050:     return createButton (enText, KeyEvent.VK_UNDEFINED, listener);
  1051:   }  //createButton(String,ActionListener)
  1052:   public static JButton createButton (String enText, int mnemonic, ActionListener listener) {
  1053:     JButton button = new JButton ();
  1054:     return setButtonCommons (button, enText, mnemonic, listener);  //ボタンの共通の設定
  1055:   }  //createButton(String,int,ActionListener)
  1056: 
  1057:   //button = createButton (image, enText, listener)
  1058:   //button = createButton (image, enText, mnemonic, listener)
  1059:   //button = createButton (image, disabledImage, enText, listener)
  1060:   //button = createButton (image, disabledImage, enText, mnemonic, listener)
  1061:   //  アイコンとテキストのボタンを作る
  1062:   public static JButton createButton (Image image, String enText, ActionListener listener) {
  1063:     return createButton (image, null, enText, KeyEvent.VK_UNDEFINED, listener);
  1064:   }  //createButton(Image,String,ActionListener)
  1065:   public static JButton createButton (Image image, String enText, int mnemonic, ActionListener listener) {
  1066:     return createButton (image, null, enText, mnemonic, listener);
  1067:   }  //createButton(Image,String,int,ActionListener)
  1068:   public static JButton createButton (Image image, Image disabledImage, String enText, ActionListener listener) {
  1069:     return createButton (image, disabledImage, enText, KeyEvent.VK_UNDEFINED, listener);
  1070:   }  //createButton(Image,Image,String,ActionListener)
  1071:   public static JButton createButton (Image image, Image disabledImage, String enText, int mnemonic, ActionListener listener) {
  1072:     JButton button = new JButton (new ImageIcon (image));
  1073:     if (disabledImage != null) {
  1074:       button.setDisabledIcon (new ImageIcon (disabledImage));
  1075:     }
  1076:     button.setBorder (new EmptyBorder (1, 1, 1, 1));
  1077:     button.setIconTextGap (3);
  1078:     return setButtonCommons (button, enText, mnemonic, listener);  //ボタンの共通の設定
  1079:   }  //createButton(Image,Image,String,int,ActionListener)
  1080: 
  1081:   //button = createIconButton (icon, enToolTipText, listener)
  1082:   //button = createIconButton (icon, disabledIcon, enToolTipText, listener)
  1083:   //button = createImageButton (image, enToolTipText, listener)
  1084:   //button = createImageButton (image, disabledImage, enToolTipText, listener)
  1085:   //  アイコンのみのボタンを作る
  1086:   //  ツールチップテキストをそのままアクションコマンドにする
  1087:   public static JButton createIconButton (ImageIcon icon, String enToolTipText, ActionListener listener) {
  1088:     return createIconButton (icon, null, enToolTipText, listener);
  1089:   }  //createIconButton(ImageIcon,String,ActionListener)
  1090:   public static JButton createIconButton (ImageIcon icon, ImageIcon disabledIcon, String enToolTipText, ActionListener listener) {
  1091:     JButton button = new JButton (icon);
  1092:     if (disabledIcon != null) {
  1093:       button.setDisabledIcon (disabledIcon);
  1094:     }
  1095:     //button.setContentAreaFilled (false);
  1096:     button.setBorder (new EmptyBorder (1, 1, 1, 1));
  1097:     //button.setBorderPainted (false);
  1098:     //button.setMargin (new Insets (0, 0, 0, 0));
  1099:     if (enToolTipText != null) {
  1100:       button.setToolTipText (enToolTipText);
  1101:       button.setActionCommand (enToolTipText);
  1102:     }
  1103:     return addListener (button, listener);
  1104:   }  //createIconButton(ImageIcon,ImageIcon,String,ActionListener)
  1105:   public static JButton createImageButton (Image image, String enToolTipText, ActionListener listener) {
  1106:     return createImageButton (image, null, enToolTipText, listener);
  1107:   }  //createImageButton(Image,String,ActionListener)
  1108:   public static JButton createImageButton (Image image, Image disabledImage, String enToolTipText, ActionListener listener) {
  1109:     JButton button = new JButton (new ImageIcon (image));
  1110:     if (disabledImage != null) {
  1111:       button.setDisabledIcon (new ImageIcon (disabledImage));
  1112:     }
  1113:     //button.setContentAreaFilled (false);
  1114:     button.setBorder (new EmptyBorder (1, 1, 1, 1));
  1115:     //button.setBorderPainted (false);
  1116:     //button.setMargin (new Insets (0, 0, 0, 0));
  1117:     if (enToolTipText != null) {
  1118:       button.setToolTipText (enToolTipText);
  1119:       button.setActionCommand (enToolTipText);
  1120:     }
  1121:     return addListener (button, listener);
  1122:   }  //createImageButton(Image,Image,String,ActionListener)
  1123: 
  1124:   //button = createCheckBox (selected, enText, listener)
  1125:   //button = createCheckBox (selected, enText, mnemonic, listener)
  1126:   //  チェックボックスを作る
  1127:   public static JCheckBox createCheckBox (boolean selected, String enText, ActionListener listener) {
  1128:     return createCheckBox (selected, enText, KeyEvent.VK_UNDEFINED, listener);
  1129:   }  //createCheckBox(boolean,String,ActionListener)
  1130:   public static JCheckBox createCheckBox (boolean selected, String enText, int mnemonic, ActionListener listener) {
  1131:     JCheckBox button = new JCheckBox ();
  1132:     button.setBorder (new EmptyBorder (0, 0, 0, 0));
  1133:     button.setSelected (selected);
  1134:     return setButtonCommons (button, enText, mnemonic, listener);  //ボタンの共通の設定
  1135:   }  //createCheckBox(boolean,String,int,ActionListener)
  1136: 
  1137:   //button = createIconCheckBox (selected, image, selectedImage, enToolTipText, listener)
  1138:   //button = createIconCheckBox (selected, image, selectedImage, disabledImage, disabledSelectedImage, enToolTipText, listener)
  1139:   //  アイコンチェックボックスを作る
  1140:   //  ツールチップテキストをそのままアクションコマンドにする
  1141:   public static JCheckBox createIconCheckBox (boolean selected, Image image, Image selectedImage, String enToolTipText, ActionListener listener) {
  1142:     return createIconCheckBox (selected, image, selectedImage, null, null, enToolTipText, listener);
  1143:   }  //createIconCheckBox(boolean,Image,Image,String,ActionListener)
  1144:   public static JCheckBox createIconCheckBox (boolean selected, Image image, Image selectedImage, Image disabledImage, Image disabledSelectedImage, String enToolTipText, ActionListener listener) {
  1145:     JCheckBox button = new JCheckBox (new ImageIcon (image));
  1146:     button.setBorder (new EmptyBorder (1, 1, 1, 1));
  1147:     button.setSelected (selected);
  1148:     button.setSelectedIcon (new ImageIcon (selectedImage));
  1149:     if (disabledImage != null) {
  1150:       button.setDisabledIcon (new ImageIcon (disabledImage));
  1151:     }
  1152:     if (disabledSelectedImage != null) {
  1153:       button.setDisabledSelectedIcon (new ImageIcon (disabledSelectedImage));
  1154:     }
  1155:     if (enToolTipText != null) {
  1156:       button.setToolTipText (enToolTipText);
  1157:       button.setActionCommand (enToolTipText);
  1158:     }
  1159:     return addListener (button, listener);
  1160:   }  //createIconCheckBox(boolean,Image,Image,Image,Image,String,ActionListener)
  1161: 
  1162:   //radioButton = createRadioButton (group, selected, enText, listener)
  1163:   //radioButton = createRadioButton (group, selected, enText, mnemonic, listener)
  1164:   //  ラジオボタンを作る
  1165:   public static JRadioButton createRadioButton (ButtonGroup group, boolean selected, String enText, ActionListener listener) {
  1166:     return createRadioButton (group, selected, enText, KeyEvent.VK_UNDEFINED, listener);
  1167:   }  //createRadioButton(ButtonGroup,boolean,String,ActionListener)
  1168:   public static JRadioButton createRadioButton (ButtonGroup group, boolean selected, String enText, int mnemonic, ActionListener listener) {
  1169:     JRadioButton button = new JRadioButton ();
  1170:     button.setBorder (new EmptyBorder (0, 0, 0, 0));
  1171:     group.add (button);
  1172:     button.setSelected (selected);
  1173:     return setButtonCommons (button, enText, mnemonic, listener);  //ボタンの共通の設定
  1174:   }  //createRadioButton(ButtonGroup,boolean,String,int,ActionListener)
  1175: 
  1176:   //button = createIconRadioButton (group, selected, image, selectedImage, enToolTipText, listener)
  1177:   //  アイコンラジオボタンを作る
  1178:   //  ツールチップテキストをそのままアクションコマンドにする
  1179:   public static JRadioButton createIconRadioButton (ButtonGroup group, boolean selected, Image image, Image selectedImage, String enToolTipText, ActionListener listener) {
  1180:     JRadioButton button = new JRadioButton (new ImageIcon (image));
  1181:     button.setBorder (new EmptyBorder (1, 1, 1, 1));
  1182:     group.add (button);
  1183:     button.setSelected (selected);
  1184:     button.setSelectedIcon (new ImageIcon (selectedImage));
  1185:     if (enToolTipText != null) {
  1186:       button.setToolTipText (enToolTipText);
  1187:       button.setActionCommand (enToolTipText);
  1188:     }
  1189:     return addListener (button, listener);
  1190:   }  //createIconRadioButton(ButtonGroup,boolean,Image,Image,String,int,ActionListener)
  1191: 
  1192: 
  1193:   //--------------------------------------------------------------------------------
  1194:   //スライダーを作る
  1195: 
  1196:   //slider = createHorizontalSlider (min, max, value, major, minor, texts, listener)
  1197:   //  ラベルのテキストを指定してスライダーを作る
  1198:   public static JSlider createHorizontalSlider (int min, int max, int value, int major, int minor, String[] texts, ChangeListener listener) {
  1199:     JSlider slider = createHorizontalSlider (min, max, value, major, minor, listener);
  1200:     Hashtable<Integer,JComponent> table = new Hashtable<Integer,JComponent> ();
  1201:     for (int i = min; i <= max; i++) {
  1202:       if (i % major == 0 && texts[i - min] != null) {  //メジャー目盛りの位置だけ書く
  1203:         table.put (i, createLabel (texts[i - min]));
  1204:       }
  1205:     }
  1206:     slider.setLabelTable (table);
  1207:     return slider;
  1208:   }  //createHorizontalSlider(int,int,int,int,int,String[],ChangeListener)
  1209: 
  1210:   //slider = createHorizontalSlider (min, max, value, major, minor, listener)
  1211:   //  スライダーを作る
  1212:   public static JSlider createHorizontalSlider (int min, int max, int value, int major, int minor, ChangeListener listener) {
  1213:     JSlider slider = new JSlider (SwingConstants.HORIZONTAL, min, max, value);
  1214:     if (major != 0) {
  1215:       slider.setLabelTable (slider.createStandardLabels (major));
  1216:       slider.setPaintLabels (true);
  1217:       slider.setMajorTickSpacing (major);
  1218:       if (minor != 0) {
  1219:         slider.setMinorTickSpacing (minor);
  1220:       }
  1221:       slider.setPaintTicks (true);
  1222:       slider.setSnapToTicks (true);
  1223:     }
  1224:     return addListener (slider, listener);
  1225:   }  //createHorizontalSlider(int,int,int,int,int,ChangeListener)
  1226: 
  1227: 
  1228:   //--------------------------------------------------------------------------------
  1229:   //メニューを作る
  1230: 
  1231:   //menuBar = createMenuBar (component, ...)
  1232:   //  メニューバーを作る
  1233:   //  メニューアイテムを並べる
  1234:   //  nullは何も表示しない
  1235:   //  Box.createHorizontalGlue()を追加すると残りのメニューを右に寄せることができる
  1236:   public static JMenuBar createMenuBar (Component... components) {
  1237:     JMenuBar bar = new JMenuBar ();
  1238:     for (Component component : components) {
  1239:       if (component != null) {
  1240:         bar.add (component);
  1241:       }
  1242:     }
  1243:     return bar;
  1244:   }  //createMenuBar(Component...)
  1245: 
  1246:   //menu = createMenu (enText, item, ...)
  1247:   //menu = createMenu (enText, mnemonic, item, ...)
  1248:   //  メニューを作る
  1249:   //  メニューアイテムを並べる
  1250:   //  nullは何も表示しない
  1251:   //  セパレータを入れるときはcreateHorizontalSeparator()を使う
  1252:   //  JSeparatorを受け付けるためJMenuItem...ではなくJComponent...にする
  1253:   public static JMenu createMenu (String enText, JComponent... items) {
  1254:     return createMenu (enText, KeyEvent.VK_UNDEFINED, items);
  1255:   }  //createMenu(String,JComponent...)
  1256:   public static JMenu createMenu (String enText, int mnemonic, JComponent... items) {
  1257:     JMenu menu = new JMenu ();
  1258:     for (JComponent item : items) {
  1259:       if (item != null) {
  1260:         menu.add (item);
  1261:       }
  1262:     }
  1263:     //menu.setAccelerator()は実行時エラーになる
  1264:     //  java.lang.Error: setAccelerator() is not defined for JMenu.  Use setMnemonic() instead.
  1265:     return setButtonCommons (menu, enText, mnemonic, null);  //ボタンの共通の設定
  1266:   }  //createMenu(String,int,JComponent...)
  1267: 
  1268:   //popupMenu = createPopupMenu (item, ...)
  1269:   //  ポップアップメニューを作る
  1270:   //  メニューアイテムを並べる
  1271:   //  nullは何も表示しない
  1272:   //  セパレータを入れるときはcreateHorizontalSeparator()を使う
  1273:   //  JSeparatorを受け付けるためJMenuItem...ではなくJComponent...にする
  1274:   public static JPopupMenu createPopupMenu (JComponent... items) {
  1275:     JPopupMenu popupMenu = new JPopupMenu ();
  1276:     for (JComponent item : items) {
  1277:       if (item != null) {
  1278:         popupMenu.add (item);
  1279:       }
  1280:     }
  1281:     return popupMenu;
  1282:   }  //createPopupMenu(JComponent...)
  1283: 
  1284:   //item = createMenuItem (enText, listener)
  1285:   //item = createMenuItem (enText, mnemonic, listener)
  1286:   //  メニューアイテムを作る
  1287:   public static JMenuItem createMenuItem (String enText, ActionListener listener) {
  1288:     return createMenuItem (enText, KeyEvent.VK_UNDEFINED, listener);
  1289:   }  //createMenuItem(String,ActionListener)
  1290:   public static JMenuItem createMenuItem (String enText, int mnemonic, ActionListener listener) {
  1291:     return createMenuItem (enText, mnemonic, 0, listener);
  1292:   }  //createMenuItem(String,int,ActionListener)
  1293:   public static JMenuItem createMenuItem (String enText, int mnemonic, int modifiers, ActionListener listener) {
  1294:     JMenuItem item = new JMenuItem ();
  1295:     if (modifiers != 0) {
  1296:       item.setAccelerator (KeyStroke.getKeyStroke (mnemonic, modifiers));
  1297:       mnemonic = KeyEvent.VK_UNDEFINED;
  1298:     }
  1299:     return setButtonCommons (item, enText, mnemonic, listener);  //ボタンの共通の設定
  1300:   }  //createMenuItem(String,int,int,ActionListener)
  1301: 
  1302:   //item = createCheckBoxMenuItem (selected, enText, listener)
  1303:   //item = createCheckBoxMenuItem (selected, enText, mnemonic, listener)
  1304:   //  チェックボックスメニューアイテムを作る
  1305:   public static JCheckBoxMenuItem createCheckBoxMenuItem (boolean selected, String enText, ActionListener listener) {
  1306:     return createCheckBoxMenuItem (selected, enText, KeyEvent.VK_UNDEFINED, listener);
  1307:   }  //createCheckBoxMenuItem(boolean,String,ActionListener)
  1308:   public static JCheckBoxMenuItem createCheckBoxMenuItem (boolean selected, String enText, int mnemonic, ActionListener listener) {
  1309:     return createCheckBoxMenuItem (selected, enText, mnemonic, 0, listener);
  1310:   }  //createCheckBoxMenuItem(boolean,String,int,ActionListener)
  1311:   public static JCheckBoxMenuItem createCheckBoxMenuItem (boolean selected, String enText, int mnemonic, int modifiers, ActionListener listener) {
  1312:     JCheckBoxMenuItem item = new JCheckBoxMenuItem ();
  1313:     item.setSelected (selected);
  1314:     if (modifiers != 0) {
  1315:       item.setAccelerator (KeyStroke.getKeyStroke (mnemonic, modifiers));
  1316:       mnemonic = KeyEvent.VK_UNDEFINED;
  1317:     }
  1318:     return setButtonCommons (item, enText, mnemonic, listener);  //ボタンの共通の設定
  1319:   }  //createCheckBoxMenuItem(boolean,String,int,int,ActionListener)
  1320: 
  1321:   //item = createRadioButtonMenuItem (group, selected, enText, listener)
  1322:   //item = createRadioButtonMenuItem (group, selected, enText, mnemonic, listener)
  1323:   //  ラジオボタンメニューアイテムを作る
  1324:   public static JRadioButtonMenuItem createRadioButtonMenuItem (ButtonGroup group, boolean selected, String enText, ActionListener listener) {
  1325:     return createRadioButtonMenuItem (group, selected, enText, KeyEvent.VK_UNDEFINED, listener);
  1326:   }  //createRadioButtonMenuItem(ButtonGroup,boolean,String,ActionListener)
  1327:   public static JRadioButtonMenuItem createRadioButtonMenuItem (ButtonGroup group, boolean selected, String enText, int mnemonic, ActionListener listener) {
  1328:     return createRadioButtonMenuItem (group, selected, enText, mnemonic, 0, listener);
  1329:   }  //createRadioButtonMenuItem(ButtonGroup,boolean,String,int,ActionListener)
  1330:   public static JRadioButtonMenuItem createRadioButtonMenuItem (ButtonGroup group, boolean selected, String enText, int mnemonic, int modifiers, ActionListener listener) {
  1331:     JRadioButtonMenuItem item = new JRadioButtonMenuItem ();
  1332:     group.add (item);
  1333:     item.setSelected (selected);
  1334:     if (modifiers != 0) {
  1335:       item.setAccelerator (KeyStroke.getKeyStroke (mnemonic, modifiers));
  1336:       mnemonic = KeyEvent.VK_UNDEFINED;
  1337:     }
  1338:     return setButtonCommons (item, enText, mnemonic, listener);  //ボタンの共通の設定
  1339:   }  //createRadioButtonMenuItem(ButtonGroup,boolean,String,int,int,ActionListener)
  1340: 
  1341:   //setButtonCommons (button, enText, mnemonic, listener)
  1342:   //  ボタンの共通の設定
  1343:   //  ニモニックを含まないテキストをそのままアクションコマンドにする
  1344:   //  Multilingual.mlnTextがアクションコマンドを英語のテキストとして使うのでアクションリスナーを省略してもアクションコマンドは設定される
  1345:   //  ニモニックはKeyEvent.VK_~で指定する。英数字は大文字のcharで指定しても問題ない
  1346:   //  Multilingual.mlnTextがニモニックの有無をgetMnemonicで確認するのでニモニックがKeyEvent.VK_UNDEFINEDのときもそのままニモニックとして設定される
  1347:   public static <T extends AbstractButton> T setButtonCommons (T button, String enText, int mnemonic, ActionListener listener) {
  1348:     button.setMnemonic (mnemonic);
  1349:     if (mnemonic == KeyEvent.VK_UNDEFINED) {  //ニモニックがないとき
  1350:       button.setText (enText);
  1351:     } else {  //ニモニックがあるとき
  1352:       //テキストにニモニックの大文字と小文字が両方含まれているとき、大文字と小文字が一致するほうにマークを付ける
  1353:       String mnemonicText = KeyEvent.getKeyText (mnemonic);
  1354:       int index = enText.indexOf (mnemonicText);  //大文字と小文字を区別して検索する
  1355:       if (index < 0) {
  1356:         index = enText.toLowerCase ().indexOf (mnemonicText.toLowerCase ());  //大文字と小文字を区別せずに検索する
  1357:       }
  1358:       if (index >= 0) {  //ニモニックがテキストに含まれているとき
  1359:         button.setText (enText);
  1360:         button.setDisplayedMnemonicIndex (index);
  1361:       } else {  //ニモニックがテキストに含まれていないとき
  1362:         button.setText (enText + "(" + mnemonicText + ")");
  1363:         button.setDisplayedMnemonicIndex (enText.length () + 1);
  1364:       }
  1365:     }
  1366:     button.setActionCommand (enText);
  1367:     return addListener (button, listener);
  1368:   }  //setButtonCommons(T extends AbstractButton,String,int,ActionListener)
  1369: 
  1370: 
  1371:   //--------------------------------------------------------------------------------
  1372:   //スクロールリストを作る
  1373: 
  1374:   //list = createScrollList (texts, visibleRowCount, selectedIndex, listener)
  1375:   //list = createScrollList (texts, visibleRowCount, selectedIndex, selectionMode, listener)
  1376:   //  selectionMode
  1377:   //    ListSelectionModel.SINGLE_SELECTION
  1378:   //    ListSelectionModel.SINGLE_INTERVAL_SELECTION
  1379:   //    ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
  1380:   public static ScrollList createScrollList (String[] texts, int visibleRowCount, int selectedIndex, ListSelectionListener listener) {
  1381:     return createScrollList (texts, visibleRowCount, selectedIndex, ListSelectionModel.SINGLE_SELECTION, listener);
  1382:   }  //createScrollList(String[],int,int)
  1383:   public static ScrollList createScrollList (String[] texts, int visibleRowCount, int selectedIndex, int selectionMode, ListSelectionListener listener) {
  1384:     DefaultListModel<String> listModel = new DefaultListModel<String> ();
  1385:     for (String text : texts) {
  1386:       listModel.addElement (text);
  1387:     }
  1388:     ScrollList list = new ScrollList (listModel);
  1389:     list.setVisibleRowCount (visibleRowCount);
  1390:     list.setSelectionMode (selectionMode);
  1391:     list.setSelectedIndex (selectedIndex);
  1392:     return addListener (list, listener);
  1393:   }  //createScrollList(String[],int,int,int)
  1394: 
  1395: 
  1396:   //--------------------------------------------------------------------------------
  1397:   //コンボボックスを作る
  1398: 
  1399:   //comboBox = createComboBox (selectedIndex, enToolTipText, listener, text, ...)
  1400:   //  コンボボックスを作る
  1401:   public static JComboBox<String> createComboBox (int selectedIndex, String enToolTipText, ActionListener listener, String... texts) {
  1402:     JComboBox<String> comboBox = new JComboBox<String> (texts);
  1403:     comboBox.setBorder (new EmptyBorder (0, 0, 0, 0));
  1404:     comboBox.setEditable (false);
  1405:     comboBox.setSelectedIndex (selectedIndex);
  1406:     //comboBox.setMaximumRowCount (5);
  1407:     int digits = 0;
  1408:     for (String text : texts) {
  1409:       digits = Math.max (digits, text.length ());
  1410:     }
  1411:     comboBox.setMaximumSize (new Dimension (30 + 10 * digits, 20));
  1412:     comboBox.setPreferredSize (new Dimension (30 + 10 * digits, 20));
  1413:     if (enToolTipText != null) {
  1414:       comboBox.setToolTipText (enToolTipText);
  1415:       comboBox.setActionCommand (enToolTipText);
  1416:     }
  1417:     return addListener (comboBox, listener);
  1418:   }  //createComboBox(int,String,ActionListener,String...)
  1419: 
  1420: 
  1421:   //--------------------------------------------------------------------------------
  1422:   //スピナーを作る
  1423: 
  1424:   //spinner = createNumberSpinner (model, digits, listener)
  1425:   //  ナンバースピナーを作る
  1426:   public static NumberSpinner createNumberSpinner (SpinnerNumberModel model, int digits, ChangeListener listener) {
  1427:     NumberSpinner spinner = new NumberSpinner (model);
  1428:     spinner.setBorder (new LineBorder (MetalLookAndFeel.getBlack (), 1));  //black
  1429:     spinner.setPreferredSize (new Dimension (24 + (LnF.lnfFontSize * 2 / 3) * digits, LnF.lnfFontSize + 4));
  1430:     spinner.setMaximumSize (new Dimension (24 + (LnF.lnfFontSize * 2 / 3) * digits, LnF.lnfFontSize + 4));
  1431:     JSpinner.NumberEditor editor = (JSpinner.NumberEditor) spinner.getEditor ();
  1432:     editor.getFormat ().setGroupingUsed (false);  //3桁毎にグループ化しない
  1433:     JTextField textField = editor.getTextField ();
  1434:     textField.setHorizontalAlignment (JTextField.RIGHT);  //右寄せ
  1435:     //textField.setFont (LnF.lnfMonospacedFont);
  1436:     return addListener (spinner, listener);
  1437:   }  //createNumberSpinner(SpinnerNumberModel,int,ChangeListener)
  1438: 
  1439:   //spinner = createDecimalSpinner (value, minimum, maximum, stepSize)
  1440:   //spinner = createDecimalSpinner (value, minimum, maximum, stepSize, option)
  1441:   //spinner = createDecimalSpinner (value, minimum, maximum, stepSize, option, listener)
  1442:   //  10進数スピナーを作る
  1443:   public static DecimalSpinner createDecimalSpinner (int value, int minimum, int maximum, int stepSize) {
  1444:     return createDecimalSpinner (value, minimum, maximum, stepSize, 0, null);
  1445:   }  //createDecimalSpinner(int,int,int,int)
  1446:   public static DecimalSpinner createDecimalSpinner (int value, int minimum, int maximum, int stepSize, int option) {
  1447:     return createDecimalSpinner (value, minimum, maximum, stepSize, option, null);
  1448:   }  //createDecimalSpinner(int,int,int,int,int)
  1449:   public static DecimalSpinner createDecimalSpinner (int value, int minimum, int maximum, int stepSize, int option, ChangeListener listener) {
  1450:     return addListener (new DecimalSpinner (value, minimum, maximum, stepSize, option), listener);
  1451:   }  //createDecimalSpinner(int,int,int,int,int,ChangeListener)
  1452: 
  1453:   //spinner = createHex8Spinner (value, mask, reverse, listener)
  1454:   //   8桁16進数スピナーを作る
  1455:   public static Hex8Spinner createHex8Spinner (int value, int mask, boolean reverse, ChangeListener listener) {
  1456:     return addListener (new Hex8Spinner (value, mask, reverse), listener);
  1457:   }  //createHex8Spinner(int,int,boolean,ChangeListener)
  1458: 
  1459:   //spinner = createListSpinner (list, value, listener)
  1460:   //  リストスピナーを作る
  1461:   public static JSpinner createListSpinner (java.util.List<?> list, Object value, ChangeListener listener) {
  1462:     SpinnerListModel model = new SpinnerListModel (list);
  1463:     JSpinner spinner = new JSpinner (model);
  1464:     spinner.setBorder (new LineBorder (MetalLookAndFeel.getSeparatorForeground (), 1));  //primary1
  1465:     int digits = 0;
  1466:     for (Object t : list) {
  1467:       digits = Math.max (digits, String.valueOf (t).length ());
  1468:     }
  1469:     spinner.setPreferredSize (new Dimension (24 + (LnF.lnfFontSize * 2 / 3) * digits, LnF.lnfFontSize + 4));
  1470:     spinner.setMaximumSize (new Dimension (24 + (LnF.lnfFontSize * 2 / 3) * digits, LnF.lnfFontSize + 4));
  1471:     JSpinner.ListEditor editor = (JSpinner.ListEditor) spinner.getEditor ();
  1472:     JTextField textField = editor.getTextField ();
  1473:     textField.setHorizontalAlignment (JTextField.RIGHT);  //右寄せ
  1474:     //textField.setFont (LnF.lnfMonospacedFont);
  1475:     model.setValue (value);  //初期設定ではリスナーを呼び出さない
  1476:     return addListener (spinner, listener);
  1477:   }  //createListSpinner (java.util.List<?>,Object,ChangeListener)
  1478: 
  1479:   //spinner = createStringSpinner (array, index, listener)
  1480:   //  文字列スピナーを作る
  1481:   public static JSpinner createStringSpinner (String[] array, int index, ChangeListener listener) {
  1482:     ArrayList<String> list = new ArrayList<String> ();
  1483:     for (String string : array) {
  1484:       list.add (string);
  1485:     }
  1486:     return createListSpinner (list, array[index], listener);
  1487:   }  //createStringSpinner
  1488: 
  1489: 
  1490:   //--------------------------------------------------------------------------------
  1491:   //  デバッグ
  1492: 
  1493:   //printAncestorClass (object)
  1494:   //  オブジェクトのクラス、親クラス、親の親クラス…を表示する
  1495:   public static void printAncestorClass (Object object) {
  1496:     System.out.print (object);
  1497:     if (object != null) {
  1498:       Class<? extends Object> c = object.getClass ();
  1499:       for (c = c.getSuperclass (); c != null; c = c.getSuperclass ()) {
  1500:         System.out.print (" < " + c.getName ());
  1501:       }
  1502:     }
  1503:     System.out.println ();
  1504:   }
  1505: 
  1506:   //printComponentTree (component)
  1507:   //printComponentTree (component, prefix)
  1508:   //  コンポーネントのツリーを表示する
  1509:   public static void printComponentTree (Component component) {
  1510:     printComponentTree (component, "0.");
  1511:   }
  1512:   public static void printComponentTree (Component component, String prefix) {
  1513:     System.out.print (prefix + " ");
  1514:     printAncestorClass (component);
  1515:     if (component instanceof Container) {
  1516:       Container container = (Container) component;
  1517:       int n = container.getComponentCount ();
  1518:       for (int i = 0; i < n; i++) {
  1519:         printComponentTree (container.getComponent (i), "  " + prefix + i + ".");
  1520:       }
  1521:     }
  1522:   }
  1523: 
  1524: 
  1525: }  //class ComponentFactory
  1526: 
  1527: 
  1528: