1 40 41 42 43 package com.sshtools.ui.swing; 44 45 46 47 import java.awt.BorderLayout ; 48 49 import java.awt.Color ; 50 51 import java.awt.Component ; 52 53 import java.awt.Dimension ; 54 55 import java.awt.Font ; 56 57 import java.awt.FontMetrics ; 58 59 import java.awt.GraphicsEnvironment ; 60 61 import java.awt.GridBagConstraints ; 62 63 import java.awt.GridBagLayout ; 64 65 import java.awt.Insets ; 66 67 import java.awt.event.ActionEvent ; 68 69 import java.awt.event.ActionListener ; 70 71 import java.util.Vector ; 72 73 import javax.swing.AbstractListModel ; 74 75 import javax.swing.BorderFactory ; 76 77 import javax.swing.DefaultListCellRenderer ; 78 79 import javax.swing.JCheckBox ; 80 81 import javax.swing.JComponent ; 82 83 import javax.swing.JFormattedTextField ; 84 85 import javax.swing.JLabel ; 86 87 import javax.swing.JList ; 88 89 import javax.swing.JOptionPane ; 90 91 import javax.swing.JPanel ; 92 93 import javax.swing.JScrollPane ; 94 95 import javax.swing.JTextField ; 96 97 import javax.swing.SwingConstants ; 98 99 import javax.swing.UIManager ; 100 101 import javax.swing.event.DocumentEvent ; 102 103 import javax.swing.event.DocumentListener ; 104 105 import javax.swing.event.ListSelectionEvent ; 106 107 import javax.swing.event.ListSelectionListener ; 108 109 import com.sshtools.ui.swing.UIUtil; 110 111 112 113 122 123 public class FontChooser 124 125 extends JPanel { 126 127 private static FontNameListModel fontNameListModel; 128 129 private JList fontNameList; 130 131 private JList fontSizeList; 132 133 private JTextField fontName; 134 135 private Font chosenFont; 136 137 private JCheckBox bold; 138 139 private JCheckBox italic; 140 141 private JFormattedTextField fontSize; 142 143 private JLabel preview; 144 145 private boolean adjusting; 146 147 148 149 158 159 public FontChooser() { 160 161 this(null, true, false); 162 163 } 164 165 166 167 176 177 public FontChooser(Font font, boolean showSize, boolean monospacedOnly) { 178 179 super(new BorderLayout ()); 180 181 182 183 185 if (fontNameListModel == null) { 186 187 fontNameListModel = new FontNameListModel(monospacedOnly); 188 189 190 191 193 } 194 195 fontNameList = new JList (fontNameListModel); 196 197 fontNameList.setCellRenderer(new FontNameListCellRenderer()); 198 199 fontNameList.setVisibleRowCount(7); 200 201 203 fontNameList.addListSelectionListener(new ListSelectionListener () { 204 205 public void valueChanged(ListSelectionEvent e) { 206 207 if (!fontNameList.isSelectionEmpty() && 208 209 !e.getValueIsAdjusting()) { 210 211 try { 212 213 adjusting = true; 214 215 fontName.setText( ( (Font ) fontNameList. 216 217 getSelectedValue()).getName()); 218 219 } 220 221 catch (IllegalStateException iee) { 222 223 } 224 225 adjusting = false; 226 227 228 229 changeFontBasedOnState(); 230 231 } 232 233 } 234 235 }); 236 237 238 239 241 JPanel stylePanel = new JPanel (new GridBagLayout ()); 242 243 stylePanel.setBorder(BorderFactory.createTitledBorder("Font style")); 244 245 246 247 GridBagConstraints gBC = new GridBagConstraints (); 248 249 gBC.fill = GridBagConstraints.BOTH; 250 251 gBC.anchor = GridBagConstraints.CENTER; 252 253 gBC.weighty = 0.0; 254 255 gBC.insets = new Insets (2, 2, 2, 2); 256 257 258 259 ActionListener l = new ActionListener () { 260 261 public void actionPerformed(ActionEvent evt) { 262 263 changeFontBasedOnState(); 264 265 } 266 267 }; 268 269 270 271 UIUtil.jGridBagAdd(stylePanel, bold = new JCheckBox ("Bold"), gBC, 272 273 GridBagConstraints.REMAINDER); 274 275 bold.addActionListener(l); 276 277 bold.setMnemonic('b'); 278 279 UIUtil.jGridBagAdd(stylePanel, italic = new JCheckBox ("Italic"), gBC, 280 281 GridBagConstraints.REMAINDER); 282 283 italic.setMnemonic('i'); 284 285 italic.addActionListener(l); 286 287 288 289 291 293 JPanel sizePanel = null; 294 295 if(showSize) { 296 297 fontSizeList = new JList (new Integer [] { 298 299 new Integer (8), new Integer (9), new Integer (10), 300 301 new Integer (11), new Integer (12), 302 303 new Integer (14), 304 305 new Integer (16), new Integer (18), 306 307 new Integer (20), 308 309 new Integer (22), new Integer (24), 310 311 new Integer (26), 312 313 new Integer (28), new Integer (36), 314 315 new Integer (48), 316 317 new Integer (72) 318 319 }); 320 321 fontSizeList.setVisibleRowCount(4); 322 323 fontSizeList.setAutoscrolls(true); 324 325 fontSizeList.addListSelectionListener(new ListSelectionListener () { 326 327 public void valueChanged(ListSelectionEvent e) { 328 329 if (!fontNameList.isSelectionEmpty() && 330 331 !e.getValueIsAdjusting()) { 332 333 try { 334 335 fontSize.setValue( ( (Integer ) fontSizeList. 336 337 getSelectedValue())); 338 339 } 340 341 catch (IllegalStateException iee) { 342 343 } 344 345 346 347 changeFontBasedOnState(); 348 349 } 350 351 } 352 353 }); 354 355 356 357 359 sizePanel = new JPanel (new GridBagLayout ()); 360 361 sizePanel.setBorder(BorderFactory.createTitledBorder("Font size")); 362 363 364 365 366 367 GridBagConstraints gBC3 = new GridBagConstraints (); 368 369 gBC3.fill = GridBagConstraints.BOTH; 370 371 gBC3.anchor = GridBagConstraints.WEST; 372 373 gBC3.weightx = 1.0; 374 375 gBC3.weighty = 0.0; 376 377 gBC3.insets = new Insets (2, 2, 2, 2); 378 379 UIUtil.jGridBagAdd(sizePanel, new JLabel ("Size:"), gBC3, 380 381 GridBagConstraints.REMAINDER); 382 383 UIUtil.jGridBagAdd(sizePanel, 384 385 fontSize = new JFormattedTextField (new Integer (4)), 386 387 gBC3, GridBagConstraints.REMAINDER); 388 389 fontSize.getDocument().addDocumentListener(new DocumentListener () { 390 391 public void insertUpdate(DocumentEvent e) { 392 393 changeFontBasedOnState(); 394 395 } 396 397 398 399 public void removeUpdate(DocumentEvent e) { 400 401 changeFontBasedOnState(); 402 403 } 404 405 406 407 public void changedUpdate(DocumentEvent e) { 408 409 changeFontBasedOnState(); 410 411 } 412 413 }); 414 415 gBC3.weighty = 1.0; 416 417 UIUtil.jGridBagAdd(sizePanel, new JScrollPane (fontSizeList), gBC3, 418 419 GridBagConstraints.REMAINDER); 420 421 } 422 423 424 425 427 JPanel namePanel = new JPanel (new GridBagLayout ()); 428 429 namePanel.setBorder(BorderFactory.createTitledBorder("Font name")); 430 431 432 433 GridBagConstraints gBC2 = new GridBagConstraints (); 434 435 gBC2.fill = GridBagConstraints.BOTH; 436 437 gBC2.anchor = GridBagConstraints.WEST; 438 439 gBC2.weightx = 1.0; 440 441 gBC2.weighty = 0.0; 442 443 gBC2.insets = new Insets (2, 2, 2, 2); 444 445 UIUtil.jGridBagAdd(namePanel, new JLabel ("Name:"), gBC2, 446 447 GridBagConstraints.REMAINDER); 448 449 UIUtil.jGridBagAdd(namePanel, fontName = new JTextField (10), gBC2, 450 451 GridBagConstraints.REMAINDER); 452 453 gBC2.weighty = 1.0; 454 455 UIUtil.jGridBagAdd(namePanel, new JScrollPane (fontNameList), gBC2, 456 457 GridBagConstraints.REMAINDER); 458 459 460 461 463 preview = new JLabel ("Some sample text") { 464 465 public Dimension getMinimumSize() { 466 467 return new Dimension (super.getMinimumSize().width, 64); 468 469 } 470 471 472 473 public Dimension getPreferredSize() { 474 475 return new Dimension (320, 64); 476 477 } 478 479 }; 480 481 preview.setBackground(Color.white); 482 483 preview.setForeground(Color.black); 484 485 preview.setOpaque(true); 486 487 preview.setHorizontalAlignment(SwingConstants.CENTER); 488 489 preview.setBorder(BorderFactory.createLineBorder(Color.black)); 490 491 492 493 495 JPanel previewPanel = new JPanel (new BorderLayout ()); 496 497 previewPanel.setBorder(BorderFactory.createTitledBorder("Preview")); 498 499 previewPanel.add(preview, BorderLayout.CENTER); 500 501 502 503 505 JPanel rightPanel = new JPanel (new BorderLayout ()); 506 507 rightPanel.add(stylePanel, BorderLayout.NORTH); 508 509 if(sizePanel != null) { 510 511 rightPanel.add(sizePanel, BorderLayout.CENTER); 512 513 } 514 515 516 517 519 521 fontName.getDocument().addDocumentListener(new DocumentListener () { 522 523 public void insertUpdate(DocumentEvent e) { 524 525 if(!adjusting) { 526 527 findClosestFont(); 528 529 } 530 531 } 532 533 534 535 public void removeUpdate(DocumentEvent e) { 536 537 if(!adjusting) { 538 539 findClosestFont(); 540 541 } 542 543 } 544 545 546 547 public void changedUpdate(DocumentEvent e) { 548 549 if(!adjusting) { 550 551 findClosestFont(); 552 553 } 554 555 } 556 557 }); 558 559 560 561 563 add(namePanel, BorderLayout.CENTER); 564 565 add(rightPanel, BorderLayout.EAST); 566 567 add(previewPanel, BorderLayout.SOUTH); 568 569 570 571 573 setChosenFont(font); 574 575 } 576 577 578 579 private void findClosestFont() { 580 581 for (int i = 0; i < fontNameList.getModel().getSize(); i++) { 582 583 Font f = (Font ) fontNameList.getModel().getElementAt(i); 584 585 586 587 if (f.getName().toLowerCase().startsWith(fontName.getText() 588 589 .toLowerCase())) { 590 591 if(fontNameList.getSelectedIndex() != i) { 592 593 fontNameList.setSelectedIndex(i); 594 595 fontNameList.scrollRectToVisible(fontNameList.getCellBounds(i, 596 597 i)); 598 599 changeFontBasedOnState(); 600 601 } 602 603 604 605 break; 606 607 } 608 609 } 610 611 } 612 613 614 615 private void changeFontBasedOnState() { 616 617 Font f = ( (Font ) fontNameList.getSelectedValue()); 618 619 620 621 if (f != null) { 622 623 int size = fontSize == null ? ( chosenFont == null ? 12 : chosenFont.getSize() ) : ((Integer )fontSize.getValue()).intValue(); 624 625 int style = (bold.isSelected() ? Font.BOLD : 0) | 626 627 (italic.isSelected() ? Font.ITALIC : 0); 628 629 chosenFont = new Font (f.getName(), style, size); 630 631 preview.setFont(chosenFont); 632 633 } 634 635 } 636 637 638 639 648 649 public void setChosenFont(Font f) { 650 651 653 if (f == null) { 654 655 f = UIManager.getFont("Label.font"); 656 657 658 659 661 } 662 663 fontName.setText(f.getName()); 664 665 findClosestFont(); 666 667 if(fontSize != null) { 668 669 fontSize.setValue(new Integer (f.getSize())); 670 671 } 672 673 bold.setSelected(f.isBold()); 674 675 italic.setSelected(f.isItalic()); 676 677 chosenFont = f; 678 679 preview.setFont(f); 680 681 } 682 683 684 685 694 695 public Font getChosenFont() { 696 697 return chosenFont; 698 699 } 700 701 702 703 708 709 public static Font showDialog(JComponent parent, Font initialFont) { 710 711 return showDialog(parent, initialFont, true, false); 712 713 } 714 715 720 721 public static Font showDialog(JComponent parent, Font initialFont, boolean showSize, boolean monospacedOnly) { 722 723 725 final FontChooser fc = new FontChooser(initialFont, showSize, monospacedOnly); 726 727 fc.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); 728 729 if(JOptionPane.showConfirmDialog(parent, fc, "Choose Font", JOptionPane.OK_CANCEL_OPTION) == 730 731 JOptionPane.OK_OPTION) { 732 733 return fc.getChosenFont(); 734 735 736 737 } 738 739 return null; 740 741 } 742 743 744 745 747 class FontNameListModel 748 749 extends AbstractListModel 750 751 implements Runnable { 752 753 private Vector fonts; 754 755 private boolean monospacedOnly; 756 757 758 759 FontNameListModel(boolean monospacedOnly) { 760 761 fonts = new Vector (); 762 763 this.monospacedOnly = monospacedOnly; 764 765 766 767 Thread t = new Thread (this); 768 769 t.start(); 770 771 } 772 773 774 775 public void run() { 776 777 Font [] f = GraphicsEnvironment.getLocalGraphicsEnvironment() 778 779 .getAllFonts(); 780 781 782 783 for (int i = 0; i < f.length; i++) { 784 785 if(!monospacedOnly || isMonospaced(f[i])) { 786 787 fonts.addElement(f[i]); 788 789 } 790 791 792 793 } 794 795 fireContentsChanged(this, 0, getSize() - 1); 796 797 } 798 799 800 801 boolean isMonospaced(Font f) { 802 803 int width = -1; 804 805 FontMetrics fm = getFontMetrics(f); 806 807 for(char i = ' '; i <= 'z'; i++) { 808 809 int cw = fm.charWidth(i); 810 811 if(width == -1 || cw == width) { 812 813 width = cw; 814 815 } 816 817 else { 818 819 return false; 820 821 } 822 823 } 824 825 return true; 826 827 828 829 } 830 831 832 833 public Object getElementAt(int i) { 834 835 return fonts.elementAt(i); 836 837 } 838 839 840 841 public int getSize() { 842 843 return fonts.size(); 844 845 } 846 847 } 848 849 850 851 853 class FontNameListCellRenderer 854 855 extends DefaultListCellRenderer { 856 857 public Component getListCellRendererComponent(JList list, Object value, 858 859 int index, boolean isSelected, boolean cellHasFocus) { 860 861 super.getListCellRendererComponent(list, value, index, isSelected, 862 863 cellHasFocus); 864 865 setText( ( (Font ) value).getName()); 866 867 868 869 return this; 870 871 } 872 873 } 874 875 } 876 877 | Popular Tags |