Java记事本自定义FontChooser类:setFont()方法使用疑问求助
Hey there! Let's work through building that custom FontChooser for your Java Notepad and clear up the confusion around using setFont(). I’ll break this down step by step so it aligns with the native Notepad’s behavior.
1. Lay Out Your Custom FontChooser Dialog
First, create a JDialog that mimics the native font picker. You’ll want components like:
- A dropdown (
JComboBox) for font names (pulled fromGraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames()) - A text field/spinner for font size
- A list (
JList) or checkboxes for styles: Plain, Bold, Italic (native Notepad uses checkboxes for Bold/Italic, with Plain as the default state—adjust based on your preference) - OK/Cancel buttons to confirm or discard changes
2. Handling Font Styles Properly
Font styles in Java are integer constants: Font.PLAIN (0), Font.BOLD (1), Font.ITALIC (2). Unlike some other controls, styles can be combined (e.g., Bold + Italic = 3). If you’re using a list for styles, here’s how to map selections to the correct style value:
- If using a single-selection list: Map each list item directly to its constant (e.g., selecting "Bold" gives
Font.BOLD) - If supporting multiple selections (like native Notepad’s checkboxes): Sum the constants for selected styles (e.g., Bold + Italic =
Font.BOLD | Font.ITALIC)
Pro tip: Instead of comparing string values (which can lead to bugs if typos happen), bind each list item to its corresponding style integer. For example, create a simple helper class:
class FontStyleOption { private String displayName; private int style; public FontStyleOption(String displayName, int style) { this.displayName = displayName; this.style = style; } public int getStyle() { return style; } @Override public String toString() { return displayName; } // Shows in the list }
Then populate your list with these objects:
JList<FontStyleOption> styleList = new JList<>(new FontStyleOption[] { new FontStyleOption("Plain", Font.PLAIN), new FontStyleOption("Bold", Font.BOLD), new FontStyleOption("Italic", Font.ITALIC) });
3. Fixing the setFont() Confusion (Your temp==list2 Logic)
I suspect your confusion comes from comparing selected items incorrectly or not creating a new Font object properly (since Font is immutable—you can’t modify an existing one, you have to create a new instance).
Here’s the correct workflow when the user confirms their font choice:
- Get the selected font name from the dropdown
- Get the selected size (parse it to an integer)
- Get the selected style(s) from your list/checkboxes
- Create a new
Fontinstance with these values - Call
setTextComponent.setFont(newFont)on your text area/field
If you were using string comparisons (like checking if temp equals "Bold"), switch to using the helper class above to avoid errors. For example, if you have a single-selection list:
FontStyleOption selectedStyle = styleList.getSelectedValue(); int style = selectedStyle != null ? selectedStyle.getStyle() : Font.PLAIN; // Get font name and size String fontName = (String) fontNameCombo.getSelectedItem(); int fontSize = Integer.parseInt(sizeTextField.getText()); // Create new font and apply it Font newFont = new Font(fontName, style, fontSize); yourTextArea.setFont(newFont);
If you were trying to compare objects directly (like temp == list2.get(1)), remember that object equality in Java uses equals() for content comparison, not == (which checks reference equality). Using the helper class avoids this entirely since you can directly retrieve the style integer.
Full Example Snippet of Custom FontChooser
Here’s a condensed version of how the dialog might work:
public class CustomFontChooser extends JDialog { private JComboBox<String> fontNameCombo; private JTextField sizeTextField; private JList<FontStyleOption> styleList; private boolean approved = false; private Font selectedFont; public CustomFontChooser(Frame parent, Font initialFont) { super(parent, "Font", true); setLayout(new BorderLayout()); // Populate font names String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); fontNameCombo = new JComboBox<>(fontNames); fontNameCombo.setSelectedItem(initialFont.getFontName()); // Size field sizeTextField = new JTextField(String.valueOf(initialFont.getSize()), 5); // Style list styleList = new JList<>(new FontStyleOption[] { new FontStyleOption("Plain", Font.PLAIN), new FontStyleOption("Bold", Font.BOLD), new FontStyleOption("Italic", Font.ITALIC) }); // Set initial selection based on current font style for (FontStyleOption option : styleList.getModel().toArray()) { if (option.getStyle() == initialFont.getStyle()) { styleList.setSelectedValue(option, true); break; } } // Buttons JButton okBtn = new JButton("OK"); okBtn.addActionListener(e -> { try { String name = (String) fontNameCombo.getSelectedItem(); int size = Integer.parseInt(sizeTextField.getText()); int style = styleList.getSelectedValue().getStyle(); selectedFont = new Font(name, style, size); approved = true; dispose(); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(this, "Invalid font size!", "Error", JOptionPane.ERROR_MESSAGE); } }); JButton cancelBtn = new JButton("Cancel"); cancelBtn.addActionListener(e -> dispose()); JPanel btnPanel = new JPanel(); btnPanel.add(okBtn); btnPanel.add(cancelBtn); // Assemble dialog JPanel topPanel = new JPanel(new GridLayout(3, 2)); topPanel.add(new JLabel("Font:")); topPanel.add(fontNameCombo); topPanel.add(new JLabel("Size:")); topPanel.add(sizeTextField); topPanel.add(new JLabel("Style:")); topPanel.add(new JScrollPane(styleList)); add(topPanel, BorderLayout.CENTER); add(btnPanel, BorderLayout.SOUTH); pack(); setLocationRelativeTo(parent); } public boolean isApproved() { return approved; } public Font getSelectedFont() { return selectedFont; } }
To use this in your Notepad:
// When user clicks "Font" menu item CustomFontChooser fontChooser = new CustomFontChooser(this, yourTextArea.getFont()); fontChooser.setVisible(true); if (fontChooser.isApproved()) { yourTextArea.setFont(fontChooser.getSelectedFont()); }
This matches the native Notepad’s behavior and clears up any confusion around setFont()—remember, always create a new Font instance with your desired properties, since existing Font objects can’t be modified.
内容的提问来源于stack exchange,提问作者Love

