How to change font size of JButton according to its size?
我有一个Java应用程序-计算器。 我想通过调整应用程序窗口的大小来动态调整按钮的字体大小。 如何执行呢?
我的想法是使用ComponentEvents。 我有应用程序窗口的初始大小和初始字体的大小。 我想根据按钮的大小更改字体大小,受窗口大小更改的影响。 问题是如何在替代方法中使用[初始窗口大小] / [初始字体大小]的比值? 每种字体的比率都不同。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | import javax.swing.*; import java.awt.*; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; public class Main extends JFrame { public Main() { super("Test"); JPanel cPane = (JPanel) getContentPane(); cPane.setLayout(new BorderLayout()); MyButton sampleButton = new MyButton("Sample text"); sampleButton.setFont(new Font("Sans Serif", Font.PLAIN, 20)); MyButton a, b, c, d; a = new MyButton("a"); b = new MyButton("b"); c = new MyButton("c"); d = new MyButton("d"); cPane.add(a, BorderLayout.PAGE_START); cPane.add(b, BorderLayout.PAGE_END); cPane.add(c, BorderLayout.LINE_START); cPane.add(d, BorderLayout.LINE_END); cPane.add(sampleButton, BorderLayout.CENTER); setSize(300, 200); setResizable(true); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setVisible(true); } public static void main(String... args) { new Main(); } class MyButton extends JButton implements ComponentListener { public MyButton(String title) { super(title); } @Override public void componentResized(ComponentEvent e) { //resizing font } @Override public void componentMoved(ComponentEvent e) { } @Override public void componentShown(ComponentEvent e) { } @Override public void componentHidden(ComponentEvent e) { } } } |
使用
-
除非将帧设置为可见并添加
ComponentListener 之间没有延迟,否则GUI有点不稳定。 我通过使用单发SwingTimer 延迟添加侦听器来解决此问题。 -
Is基于
Calculet ,它是使用ScriptEngine 的功能全面(如果简单的话)的计算器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | import java.awt.*; import java.awt.event.*; import java.awt.font.*; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.util.ArrayList; import javax.script.*; import javax.swing.border.Border; class SwingCalculator implements ActionListener, KeyListener { JTextField io; ScriptEngine engine; ArrayList<JButton> controls; final BufferedImage textImage = new BufferedImage( 100, 100, BufferedImage.TYPE_INT_ARGB); public int getMaxFontSizeForControls() { Graphics2D g = textImage.createGraphics(); FontRenderContext frc = g.getFontRenderContext(); int maxSize = 500; for (JButton b : controls) { // skip the = button.. if (!b.getText().equals("=")) { int max = getMaxFontSizeForControl(b, frc); if (maxSize > max) { maxSize = max; } } } g.dispose(); return maxSize; } public int getMaxFontSizeForControl(JButton button, FontRenderContext frc) { Rectangle r = button.getBounds(); Insets m = button.getMargin(); Insets i = button.getBorder().getBorderInsets(button); Rectangle viewableArea = new Rectangle( r.width - (m.right + m.left + i.left + i.right), r.height - (m.top + m.bottom + i.top + i.bottom) ); Font font = button.getFont(); int size = 1; boolean tooBig = false; while (!tooBig) { Font f = font.deriveFont((float) size); GlyphVector gv = f.createGlyphVector(frc, button.getText()); Rectangle2D box = gv.getVisualBounds(); if (box.getHeight() > viewableArea.getHeight() || box.getWidth() > viewableArea.getWidth()) { tooBig = true; size--; } size++; } return size; } SwingCalculator() { // obtain a reference to the JS engine engine = new ScriptEngineManager().getEngineByExtension("js"); JPanel gui = new JPanel(new BorderLayout(2, 2)); controls = new ArrayList<JButton>(); JPanel text = new JPanel(new GridLayout(0, 1, 3, 3)); gui.add(text, BorderLayout.NORTH); io = new JTextField(15); Font font = io.getFont(); font = font.deriveFont(font.getSize() * 1.7f); io.setFont(font); io.setHorizontalAlignment(SwingConstants.TRAILING); io.setFocusable(false); text.add(io); JPanel buttons = new JPanel(new GridLayout(4, 4, 2, 2)); gui.add(buttons, BorderLayout.CENTER); addButton(buttons,"7"); addButton(buttons,"8"); addButton(buttons,"9"); addButton(buttons,"/"); addButton(buttons,"4"); addButton(buttons,"5"); addButton(buttons,"6"); addButton(buttons,"*"); addButton(buttons,"1"); addButton(buttons,"2"); addButton(buttons,"3"); addButton(buttons,"-"); addButton(buttons,"0"); addButton(buttons,"."); addButton(buttons,"C"); addButton(buttons,"+"); JButton equals = new JButton("="); equals.addKeyListener(this); controls.add(equals); equals.addActionListener(this); gui.add(equals, BorderLayout.EAST); gui.setBorder(new EmptyBorder(5, 5, 5, 5)); final JFrame f = new JFrame("Calculet"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setContentPane(gui); f.pack(); f.setMinimumSize(f.getSize()); f.setLocationByPlatform(true); f.setVisible(true); final ComponentListener cl = new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { int ii = getMaxFontSizeForControls(); for (JButton b : controls) { if (!b.getText().equals("=")) { b.setFont(b.getFont().deriveFont((float) ii)); } } } }; ActionListener al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { f.addComponentListener(cl); } }; Timer t = new Timer(500, al); t.setRepeats(false); t.start(); } public void addButton(Container c, String text) { JButton b = new JButton(text); b.addActionListener(this); b.addKeyListener(this); controls.add(b); c.add(b); } public void calculateResult() { try { Object result = engine.eval(io.getText()); if (result == null) { io.setText("Output was 'null'"); } else { io.setText(result.toString()); } } catch (ScriptException se) { io.setText(se.getMessage()); } } public void actionPerformed(ActionEvent ae) { String command = ae.getActionCommand(); if (command.equals("C")) { io.setText(""); } else if (command.equals("=")) { calculateResult(); } else { io.setText(io.getText() + command); } } private JButton getButton(String text) { for (JButton button : controls) { String s = button.getText(); if (text.endsWith(s) || (s.equals("=") && (text.equals("Equals") || text.equals("Enter")))) { return button; } } return null; } /* * START - Because I hate mice. */ public void keyPressed(KeyEvent ke) { } public void keyReleased(KeyEvent ke) { String s = ke.getKeyText(ke.getKeyCode()); JButton b = getButton(s); if (b != null) { b.requestFocusInWindow(); b.doClick(); } } public void keyTyped(KeyEvent ke) { } public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { new SwingCalculator(); } }; // Swing GUIs should be created and updated on the EDT // http://docs.oracle.com/javase/tutorial/uiswing/concurrency SwingUtilities.invokeLater(r); } } |
比较此处和此处显示的方法。 前者使用可用的
后者引用了使用
或