我编写了以下代码,除了信息框中的“退出信息”按钮和信息框中的文本之外,它似乎运行顺利。首先,信息框中的文本(位于标签上)拒绝显示。其次,“退出信息”按钮没有出现在我为其设置的位置。关于我可以做些什么来使其正常运行有什么建议吗? 谢谢
注意:我对 Java 非常缺乏经验,因此可能无法完全理解答案,除非它们是为幼儿园学生编写的:)
import java.awt.*;
import javax.swing.*;
public class CombineInputWindow {
public static void main(String[] args) {
// TODO Auto-generated method stub
// Create the frame
JFrame frame = new JFrame("New GUI");// Title the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// add close function
// Create the label:
JLabel textLabel = new JLabel("");// No text is added
textLabel.setPreferredSize(new Dimension(320,240));// Set the size of the label
frame.getContentPane().add(textLabel, BorderLayout.CENTER);// Add the label to the frame
// The following three lines set the frame up further
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
// Create the panel
JPanel panel = new JPanel();
frame.add(panel);// Add panel to frame
// Create lbutton (size, text, etc.)
JButton lbutton = new JButton("Move Left");
panel.add(lbutton);
lbutton.setSize(128,32);
lbutton.setVisible(true);
lbutton.setLocation(0,208);
// Create rbutton (size, text, etc.)
JButton rbutton = new JButton("Move right");
panel.add(rbutton);
rbutton.setSize(128,32);
rbutton.setVisible(true);
rbutton.setLocation(192,208);
// Create dodge button (size, text, etc.)
JButton btndodge = new JButton("Duck");
panel.add(btndodge);
btndodge.setSize(64,32);
btndodge.setVisible(true);
btndodge.setLocation(128,208);
// Create exit button (size, text, etc.)
JButton btnexit = new JButton("Exit");
panel.add(btnexit);
btnexit.setSize(64,32);
btnexit.setVisible(true);
btnexit.setLocation(256,0);
// Create info button (size, text, etc.)
JButton btninfo = new JButton("Info");
panel.add(btninfo);
btninfo.setSize(64,32);
btninfo.setVisible(true);
btninfo.setLocation(192,0);
// Add function to the lbutton for mouse event
lbutton.addMouseListener(new java.awt.event.MouseAdapter() {
int vbtnclicks = 0;
public void mouseClicked(java.awt.event.MouseEvent evt) {
vbtnclicks = vbtnclicks + 1;
//The following code prints out the number of times the user has clicked the button
if (vbtnclicks > 2) {
System.out.println("You moved left " + vbtnclicks + " times!");
}
else if (vbtnclicks == 1) {
System.out.println("You moved left once!");
}
else if (vbtnclicks == 2){
System.out.println("You moved left twice!");
}
else {
// The following code should not have to show up
System.out.println("I get the sense this code has been meddled with...");
}
}
});
// Add mouse event for rbutton
rbutton.addMouseListener(new java.awt.event.MouseAdapter() {
int cbtnclicks = 0;
public void mouseClicked(java.awt.event.MouseEvent evt) {
cbtnclicks = cbtnclicks + 1;
//The following code prints out the number of times the user has clicked the button
if (cbtnclicks > 2) {
System.out.println("You moved right " + cbtnclicks + " times!");
}
else if (cbtnclicks == 1) {
System.out.println("You moved right once!");
}
else if (cbtnclicks == 2){
System.out.println("You moved right twice!");
}
else {
// The following code should not have to show up
System.out.println("I get the sense this code has been meddled with...");
}
}
});
// Add mouse event for btndodge
btndodge.addMouseListener(new java.awt.event.MouseAdapter() {
int dbtnclicks = 0;
public void mouseClicked(java.awt.event.MouseEvent evt) {
dbtnclicks = dbtnclicks + 1;
//The following code prints out the number of times the user has clicked the button
if (dbtnclicks > 2) {
System.out.println("You ducked " + dbtnclicks + " times!");
}
else if (dbtnclicks == 1) {
System.out.println("You ducked once!");
}
else if (dbtnclicks == 2){
System.out.println("You ducked twice!");
}
else {
// The following code should not have to show up
System.out.println("I get the sense this code has been meddled with...");
}
}
});
// Add mouse event and exit command to the exit button
btnexit.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
System.exit(0);
}
});
// Add function to the "Info" button
btninfo.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
// Open an Info Window with specific settings
JFrame inframe = new JFrame("Info");
JLabel inlabel = new JLabel("This is the info text.");
inlabel.setPreferredSize(new Dimension(300,100));
inframe.getContentPane().add(inlabel, BorderLayout.CENTER);
inframe.setLocationRelativeTo(null);
inframe.pack();
inframe.setVisible(true);
JPanel inpanel = new JPanel();
inframe.add(inpanel);
JButton inextbtn = new JButton("Exit Info");
inpanel.add(inextbtn);
inextbtn.setSize(96,24);
inextbtn.setVisible(true);
inextbtn.setLocation(0,0);
inextbtn.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
inframe.dispose();
}
});
}
});
}
}
最佳答案
您的主要问题(infoLabel 未显示)是由于您在将 JPanel 添加到其 contentPane 之前在其 JFrame 上调用了 setVisible(true)
。将所有组件添加到 JFrame 之后始终调用 setVisible(true)
。由于 inFrame 使用 BorderLayout,您还可以通过将 JPanel 添加到 JFrame 来覆盖 JLabel。
其他问题:
- 是的,对 JButton 使用 ActionListener,而不是 MouseListener。如果按钮获得焦点并且按下空格键,ActionListener 将做出响应——这是预期的且正确的行为。 MouseListener 不会。另外,如果禁用 JButton,ActionListener 将无法工作,这也是预期的且正确的,而 MouseListener 在这里又会出现错误。
- 不要设置 GUI 组件的绝对大小或位置,而是让组件默认首选大小,然后容器布局管理器为您完成这项繁重的工作。
- 信息窗口应该是 JDialog 而不是 JFrame,因为可见应用程序应该只有一个主框架窗口,即一个 JFrame。
例如:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class CombineInput2 {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MainPanel mainPanel = new MainPanel();
JFrame frame = new JFrame("Main GUI");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
class MainPanel extends JPanel {
public MainPanel() {
setPreferredSize(new Dimension(400, 400));
add(new JButton(new InfoAction("Info", this)));
add(new JButton(new ExitAction()));
}
}
class InfoAction extends AbstractAction {
private MainPanel mainPanel;
private JDialog dialog;
public InfoAction(String name, MainPanel mainPanel) {
super(name);
this.mainPanel = mainPanel;
}
@Override
public void actionPerformed(ActionEvent e) {
if (dialog == null) {
Window win = SwingUtilities.getWindowAncestor(mainPanel);
dialog = new JDialog(win, "Info", ModalityType.APPLICATION_MODAL);
dialog.add(new DialogPanel());
dialog.pack();
dialog.setLocationRelativeTo(win);
}
dialog.setVisible(true);
}
}
class DialogPanel extends JPanel {
private static final int DP_WIDTH = 250;
private static final int DP_HEIGHT = 100;
private String text = "This is the info text.";
private JLabel infoLabel = new JLabel(text, SwingConstants.CENTER);
public DialogPanel() {
JPanel btnPanel = new JPanel();
Action exitAction = new ExitAction();
exitAction.putValue(Action.NAME, "Exit Info");
btnPanel.add(new JButton(exitAction));
setLayout(new BorderLayout());
add(infoLabel, BorderLayout.CENTER);
add(btnPanel, BorderLayout.PAGE_START);
}
@Override
public Dimension getPreferredSize() {
Dimension prefSz = super.getPreferredSize();
if (isPreferredSizeSet()) {
return prefSz;
}
int width = Math.max(prefSz.width, DP_WIDTH);
int height = Math.max(prefSz.height, DP_HEIGHT);
return new Dimension(width, height);
}
}
class ExitAction extends AbstractAction {
public ExitAction() {
super("Exit");
putValue(MNEMONIC_KEY, KeyEvent.VK_X);
}
@Override
public void actionPerformed(ActionEvent e) {
Component c = (Component) e.getSource();
if (c == null) {
return;
}
Window win = SwingUtilities.getWindowAncestor(c);
if (win != null) {
win.dispose();
}
}
}
关于java - 如何让 GUI 按钮正确响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40812831/