以下のコードは、ボタンをクリックすると、JMenuBar
コンポーネントのフォントを更新するボタンを中央に持つ簡単なGUIを作成します。これを行うにはJButton
のActionListener
でsetMyFont
メソッドが起動します。しかし、いくつかのリストされた試みの後、私はこれを達成することができませんでしたが、私はなぜそれに気づいていません。 setMyFont
で使用されるコードはJMenuBarが表示された後にJMenuとJMenuフォントを更新する
public void setMyFont(Font f, Font f2) {
//Attempt 1 in the hope it would autodetect that font
//had changed and just update
menuFont = f;
menuItemFont = f2;
//Attempt 2 in the hope on the repaint it would update
//the font with the new UIManager properties
UIManager.put("Menu.font", menuFont);
UIManager.put("MenuItem.font", menuItemFont);
//Attempt 3 in the hope that going over each component
//individually would update the font
for(Component comp: getComponents()) {
if(comp instanceof JMenu) {
comp.setFont(menuFont);
} else {
comp.setFont(menuItemFont);
}
}
validate();
repaint();
}
を下回っているフォントは、現在のコードでコンポーネントに更新されることはありませんが理由ですか?また、すでに作成されているにもかかわらず、コンポーネントでフォントを更新できるようにするためにコードを変更するにはどうすればよいですか? SSCCEため
完全なコード
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.UIManager;
public class Main extends JFrame {
private static final long serialVersionUID = 3206847208968227199L;
JButton but;
MenuBar mB;
private Main() {
setSize(600, 600);
mB = new MenuBar();
setJMenuBar(new MenuBar());
but = new JButton("Change Font");
but.addActionListener(new CustomActionListener());
add(but);
setVisible(true);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
new Main();
}
private class MenuBar extends JMenuBar {
private static final long serialVersionUID = -2055260049565317972L;
Font menuFont = new Font("Courier", Font.ITALIC + Font.BOLD, 12);
Font menuItemFont = new Font("sans-serif", 0, 12);
JMenu menu, subMenu;
MenuBar() {
UIManager.put("Menu.font", menuFont);
UIManager.put("MenuItem.font", menuItemFont);
menu = new JMenu("Menu");
subMenu = new JMenu("Sub Menu");
subMenu.add(new JMenuItem("Sub Item"));
subMenu.add(new JMenu("Sub Menu"));
menu.add(subMenu);
menu.add(new JMenuItem("Sub Item"));
menu.add(new JMenu("Sub Menu"));
add(menu);
menu = new JMenu("Another Menu");
menu.add(new JMenu("Sub Menu"));
menu.add(new JMenuItem("Sub Item"));
menu.add(new JMenu("Sub Menu"));
add(menu);
}
public void setMyFont(Font f, Font f2) {
//Attempt 1 in the hope it would autodetect that font
//had changed and just update
menuFont = f;
menuItemFont = f2;
//Attempt 2 in the hope on the repaint it would update
//the font with the new UIManager properties
UIManager.put("Menu.font", menuFont);
UIManager.put("MenuItem.font", menuItemFont);
//Attempt 3 in the hope that going over each component
//individually would update the font
for(Component comp: getComponents()) {
if(comp instanceof JMenu) {
comp.setFont(menuFont);
} else {
comp.setFont(menuItemFont);
}
}
validate();
repaint();
}
}
private class CustomActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
mB.setMyFont(new Font("sans-serif", 0, 12), new Font("Courier", Font.ITALIC + Font.BOLD, 12));
}
}
}
(1+)updateComponentTree(...)メニューバーに追加されたすべてのコンポーネントを取得するために、独自の再帰的なメソッドを記述するよりも簡単ですを使用しました。ただし、フレームではなく、メニューバーでメソッドを呼び出すだけで済みます。 – camickr
@camickr REは[docs](https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html#programmatic)に従ってメニューバー上で起動し、 'SwingUtilities updateComponentTreeUIメソッドを一度呼び出す'[最上位のコンテナ](https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html) – copeg
@copeg答えをありがとう。残念ながら、私はおそらく間違っている、 'SwingUtilities.updateComponentTreeUI(Main.this);を呼び出す'フォントを設定した後に何もしない。私は 'setMyFont'関数の外に置くべきか、それとも動作するはずです。*私も 'FontUIResource'を実装しました。違いはありませんでした。* – Dan