package org.simantics.modeling.ui.actions.style; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.GraphicsEnvironment; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BorderFactory; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListCellRenderer; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; @SuppressWarnings({"rawtypes", "unchecked"}) public class FontChooser extends JPanel { private static final long serialVersionUID = -53650261362110193L; private static Font DEFAULT_FONT = new Font(Messages.FontChooser_DefaultFont, Font.PLAIN, 16); private String sampleText; private JLabel text; private JList fontList; private JComboBox sizeComboBox; private JCheckBox boldCheckBox; private JCheckBox italicCheckBox; private String fonts[]; private Font originalFont; private Font font; public FontChooser(String sampleText) { super(); this.sampleText = sampleText; JPanel textPanel = new JPanel(); text = new JLabel(sampleText, SwingConstants.CENTER); text.setVerticalAlignment(SwingConstants.CENTER); this.setLayout(new BorderLayout()); textPanel.setBorder(BorderFactory.createLineBorder(Color.darkGray)); textPanel.add(text); textPanel.setMinimumSize(new Dimension(100, 100)); textPanel.setPreferredSize(new Dimension(200, 100)); this.add(textPanel,BorderLayout.NORTH); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); String[] ff = ge.getAvailableFontFamilyNames(); fonts = new String[ff.length + 1]; fonts[0] = Messages.FontChooser_KeepCurrentFont; System.arraycopy(ff, 0, fonts, 1, ff.length); fontList = new JList(fonts); fontList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); fontList.setLayoutOrientation(JList.VERTICAL); fontList.setVisibleRowCount(-1); fontList.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { int index = fontList.getSelectedIndex(); if (index != -1) { selectFont(index); } } } }); fontList.setCellRenderer(new FontListRenderer()); JScrollPane listScrollPane = new JScrollPane(fontList); listScrollPane.setPreferredSize(new Dimension(400, 200)); this.add(listScrollPane, BorderLayout.CENTER); JPanel controlPanel = new JPanel(); this.add(controlPanel,BorderLayout.SOUTH); ActionListener listener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { selectFont(fontList.getSelectedIndex()); } }; // FIXME: hack Integer[] sizes = {4, 6, 7, 8, 9, 10, 11, 12, 14, 18, 20, 22, 24, 36, 40, 48, 56, 64, 72, 144}; sizeComboBox = new JComboBox(sizes); sizeComboBox.addActionListener(listener); sizeComboBox.setSelectedIndex(7); controlPanel.add(new JLabel(Messages.FontChooser_Size)); controlPanel.add(sizeComboBox); boldCheckBox = new JCheckBox(Messages.FontChooser_Bold); boldCheckBox.addActionListener(listener); controlPanel.add(boldCheckBox); italicCheckBox = new JCheckBox(Messages.FontChooser_Italic); italicCheckBox.addActionListener(listener); controlPanel.add(italicCheckBox); fontList.setSelectedIndex(0); } private void selectFont(int index) { if (index < 0) return; String name = fonts[index]; Integer size = (Integer)sizeComboBox.getSelectedItem(); int style = Font.PLAIN; // plain == 0 if (boldCheckBox.isSelected()) style = style | Font.BOLD; if (italicCheckBox.isSelected()) style = style | Font.ITALIC; Font original = originalFont != null ? originalFont : DEFAULT_FONT; // Index 0 is reserved for keeping the original font (family) Font f = index == 0 ? original.deriveFont(style, size) : new Font(name, style, size); font = !f.equals(original) ? f : null; text.setText(sampleText); text.setFont(f); } public Font getFont() { return font; } public void setCurrentFont(Font font) { int index = -1; for (int i = 0; i < fonts.length; i++) { if (fonts[i].equals(font.getFamily())) { index = i; break; } } if (index == -1) return; fontList.setSelectedIndex(index); fontList.scrollRectToVisible(fontList.getCellBounds(index, index)); boldCheckBox.setSelected((font.getStyle() & Font.BOLD) > 0); italicCheckBox.setSelected((font.getStyle() & Font.ITALIC) > 0); sizeComboBox.setSelectedItem(font.getSize()); this.originalFont = font; selectFont(index); } public class FontListRenderer extends JLabel implements ListCellRenderer { private static final long serialVersionUID = 1237633327794383545L; public FontListRenderer() { setOpaque(true); setHorizontalAlignment(LEFT); setVerticalAlignment(CENTER); }; @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); } String text = (String) value; setText(text); // Not really that helpful when one can't even read the name of // some fonts with the sample text. Also keeps the list visually cleaner. // Thus removed. //setFont(index > 0 ? new Font(text,Font.PLAIN,16) : DEFAULT_FONT); return this; } } }