我正在尝试按下时按钮改变颜色。我创建了以下代码:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class KeyboardTest extends JFrame {
public static void main(String[] args) {
new KeyboardTest();
}
public KeyboardTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception ex) {
try {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setBounds(100, 100, 650, 390);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JPanel contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
add(contentPane);
contentPane.setLayout(null);
JPanel keyboardPanel = new JPanel();
keyboardPanel.setBounds(10, 122, 614, 181);
contentPane.add(keyboardPanel);
keyboardPanel.setLayout(new GridLayout(5, 0, 0, 0));
... adding panels and buttons...
addKeyBinding(A, "A", KeyEvent.VK_A);
addKeyBinding(B, "B", KeyEvent.VK_B);
addKeyBinding(C, "C", KeyEvent.VK_C);
addKeyBinding(D, "D", KeyEvent.VK_D);
addKeyBinding(E, "E", KeyEvent.VK_E);
}
protected void addKeyBinding(JButton btn, String name, int virtualKey) {
ActionMap am = getActionMap();
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke(virtualKey, 0, false), name
+ ".pressed");
im.put(KeyStroke.getKeyStroke(virtualKey, 0, true), name
+ ".released");
am.put(name + ".pressed", new KeyAction(btn, true));
am.put(name + ".released", new KeyAction(btn, false));
}
}
public class KeyAction extends AbstractAction {
private JButton btn;
private boolean highlight;
public KeyAction(JButton btn, boolean highlight) {
this.btn = btn;
this.highlight = highlight;
}
@Override
public void actionPerformed(ActionEvent e) {
if (highlight) {
btn.getModel().setPressed(true);
btn.setBackground(Color.RED);
btn.setOpaque(true);
} else {
btn.getModel().setPressed(false);
btn.setBackground(null);
btn.setOpaque(false);
}
}
}
}
这是它应该是什么样子:
以下是实际出现的内容:
我应该附上完整的代码吗? (这很长......)
答案 0 :(得分:1)
无法测试您的代码(因为您缺少组件)。而且我对你的null布局不太感兴趣。但这是一个问题和解决方案,基于我能够测试的(使用我自己的组件)。
我看到一个无用的JPanel contentPane
。您正在使用的课程已经是一个小组,我没有看到创建另一个小组的意义,然后将其包装在另一个小组中。 (虽然不是整个问题)
TestPane类有一个默认的FlowLayout,这意味着它将尊重内部组件的首选大小,即contentPane
面板。问题在于它没有首选大小。您可以使用setBounds
设置按钮大小。这与preferredSize
不同。因此,TestPane
面板没有首选大小来计算。
简单修复是将TestPane
的布局设置为BorderLayout
。这将不考虑首选大小,并将拉伸contentPane以便您可以看到它。但问题是你需要设置框架的大小。 pack()不会工作,因为整个首选尺寸交易。这就是你第一次打开它时框架闪烁的原因,因为它首先缩小了,然后用setBounds扩展它。
再次像我在评论中所说的那样,我远离空布局(因为很多原因)。你可以看到一个使用GridBagLayout here as posted in my comment的键盘的好例子,来自疯子本人@MadProgrammer