第二个 JFrame 中的组件未显示
Components in second JFrame not showing up
我想通过按下 JFrame 中的按钮来启动另一个 JFrame。
但是,如果我按下 Button,它会显示 JFrame,但不会显示其中的 Buttons 和 Sliders。
public class MainMenu extends JFrame {
private JFrame klick;
private static final long serialVersionUID = 9002;
public static void main(String[] args) {
new MainMenu();
}
public MainMenu() {
buildGUI1();
}
public void buildGUI1() throws NullPointerException {
setTitle("Hauptmenü");
setSize(800, 480);
setLayout(new GridLayout());
setAlwaysOnTop(false);
setLocation((Toolkit.getDefaultToolkit().getScreenSize().width)/4, (Toolkit.getDefaultToolkit().getScreenSize().height)/4);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
final JButton startclickbt = new JButton("Start Clicker");
startclickbt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
if(klick == null ) {
klick =new Clicker();
add(klick);
}
}
});
add(startclickbt);
}
}
第二个具有完全相同的 costructor.sliders 并且按钮不是静态的。
Buttons应该出现的地方黑屏了
希望你能帮助我:)
编辑:
public class Clicker extends JFrame {
private static final long serialVersionUID = 9001;
protected JPanel panel;
static Click j = null;
protected JSlider jsl;
protected JTextField tf;
static final int CPS_MIN= 0;
static final int CPS_MAX= 100;
static final int CPS_INIT= 25;
private int amount;
private boolean visible;
public int getDelay() {
return Math.abs(jsl.getValue()-100);
}
public int getAmount() {
return amount;
}
public boolean getVisible() {
return visible;
}
public void setOpen(boolean visible) {
this.visible=visible;
}
public Clicker(boolean visible) {
buildGUI(visible);
j = new Click(false).addPosition(new Point((Toolkit.getDefaultToolkit().getScreenSize().width)/2, (Toolkit.getDefaultToolkit().getScreenSize().height)/2)).addPosition(new Point(getLocation().x+1, getLocation().y+20));
while(true) {
j.runClicks(getDelay());
}
}
public Clicker() {
buildGUI(true);
j = new Click(false).addPosition(new Point((Toolkit.getDefaultToolkit().getScreenSize().width)/2, (Toolkit.getDefaultToolkit().getScreenSize().height)/2)).addPosition(new Point(getLocation().x+1, getLocation().y+20));
while(true) {
j.runClicks(getDelay());
}
}
public void buildGUI(boolean visible) {
setTitle("Clicker");
setSize(340, 200);
setLayout(new GridLayout());
setAlwaysOnTop(true);
setLocation(0, 0);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setVisible(visible);
final JButton bt1 = new JButton("Schließen");
bt1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
final JButton bt2 = new JButton("Start ");
bt2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
j.setClick(true);
}
});
final JButton bt3 = new JButton("Stop ");
bt3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
j.setClick(false);
JOptionPane.showMessageDialog(null, "Klicken gestoppt. Klicks: " + j.getClickAmount());
j.setClickAmout(0);
}
});
final JButton bt4 = new JButton("StartAnzahl");
bt4.addActionListener(new ActionListener() {
private int amount;
public void actionPerformed(ActionEvent e) {
String wert = tf.getText();
try {
amount = Integer.parseInt(wert);
}catch(Exception ee) {
JOptionPane.showMessageDialog(null,"Das war keine Zahl oder mehr als ein Integer");
}
j.doClick(amount);
}
});
tf = new JTextField("Anzahl gewünschte Clicks max "+ Integer.MAX_VALUE, 10);
tf.setEditable(true);
jsl = new JSlider(JSlider.HORIZONTAL,CPS_MIN,CPS_MAX,CPS_INIT);
jsl.setMinorTickSpacing(5);
jsl.setMajorTickSpacing(10);
jsl.setPaintTicks(true);
jsl.setPaintLabels(true);
panel = new JPanel();
panel.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent event) {
j.setClick(false);
}
@Override
public void mouseMoved(MouseEvent event) {
j.setClick(false);
}
});
panel.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_F1) {
j.setClick(true);
}
if(e.getKeyCode() == KeyEvent.VK_F2) {
j.setClick(false);
}
}
});
add(panel);
add(bt2);
add(bt3);
add(bt1);
add(bt4);
add(jsl);
add(tf);
pack();
}
}
尝试在构造函数的末尾使用 repaint()
或 revalidate()
。并尝试在最后调用 setVisible(true)
。
让 setVisible
成为你最后一次打电话...
public void buildGUI1() throws NullPointerException {
setTitle("Hauptmenü");
setSize(800, 480);
setLayout(new GridLayout());
setAlwaysOnTop(false);
setLocation((Toolkit.getDefaultToolkit().getScreenSize().width) / 4, (Toolkit.getDefaultToolkit().getScreenSize().height) / 4);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
final JButton startclickbt = new JButton("Start Clicker");
startclickbt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
if (klick == null) {
klick = new Clicker();
add(klick);
// Add this when you need to add/remove components
revalidate();
repaint();
}
}
});
add(startclickbt);
// Move to here
setVisible(true);
}
此外,使用 revalidate()
和 repaint()
鼓励容器在添加新组件时更新其布局
建议:
- 确保您的 UI 是在 EDT 的上下文中启动的,有关详细信息,请参阅 Initial Threads
- 避免直接从像
JFrame
这样的顶级容器扩展,而是考虑使用 JPanel
作为基础容器。这使您 UI 可以自由使用更广泛的用例,并防止您陷入困境(因为您无法将框架添加到其他框架)
- The Use of Multiple JFrames, Good/Bad Practice?
已更新
您有两个紧迫的问题
Clicker
从 JFrame
扩展,但您正试图将其添加到另一个容器,这在 Swing 中是不可能的,并且会导致异常,但是...
- 您正在使用
while (true)
循环阻塞事件调度线程,这意味着 Swing 无法处理任何新事件,包括 repaint
个事件
例如...
public Clicker(boolean visible) {
buildGUI(visible);
j = new Click(false).addPosition(new Point((Toolkit.getDefaultToolkit().getScreenSize().width) / 2, (Toolkit.getDefaultToolkit().getScreenSize().height) / 2)).addPosition(new Point(getLocation().x + 1, getLocation().y + 20));
// This is bad
while (true) {
j.runClicks(getDelay());
}
}
public Clicker() {
buildGUI(true);
j = new Click(false).addPosition(new Point((Toolkit.getDefaultToolkit().getScreenSize().width) / 2, (Toolkit.getDefaultToolkit().getScreenSize().height) / 2)).addPosition(new Point(getLocation().x + 1, getLocation().y + 20));
// This is bad
while (true) {
j.runClicks(getDelay());
}
}
现在,Click
看起来像是 UI 组件,它带来了很多其他问题,但我们没有相关代码,因此无法发表评论。
直接的解决方案可能是使用:
SwingWorker
,请参阅 Worker Threads and SwingWorker 了解更多详情
摆动 Timer
,请参阅 How to use Swing Timers 了解更多详情
- 普通老
Thread
要记住的事情
- Swing(与大多数 UI 框架一样)是单线程的,任何阻塞该线程的东西(例如永无止境的循环)都会阻止它处理新事件,包括绘制事件,这将使您的应用程序看起来喜欢它是 "hung",因为它有
- Swing 不是线程安全的。所有与 UI 的交互都必须在事件调度线程的上下文中进行。
SwingWorker
和 Swing Timer
都提供了安全更新 UI 的能力。
我想通过按下 JFrame 中的按钮来启动另一个 JFrame。 但是,如果我按下 Button,它会显示 JFrame,但不会显示其中的 Buttons 和 Sliders。
public class MainMenu extends JFrame {
private JFrame klick;
private static final long serialVersionUID = 9002;
public static void main(String[] args) {
new MainMenu();
}
public MainMenu() {
buildGUI1();
}
public void buildGUI1() throws NullPointerException {
setTitle("Hauptmenü");
setSize(800, 480);
setLayout(new GridLayout());
setAlwaysOnTop(false);
setLocation((Toolkit.getDefaultToolkit().getScreenSize().width)/4, (Toolkit.getDefaultToolkit().getScreenSize().height)/4);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
final JButton startclickbt = new JButton("Start Clicker");
startclickbt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
if(klick == null ) {
klick =new Clicker();
add(klick);
}
}
});
add(startclickbt);
}
}
第二个具有完全相同的 costructor.sliders 并且按钮不是静态的。 Buttons应该出现的地方黑屏了
希望你能帮助我:)
编辑:
public class Clicker extends JFrame {
private static final long serialVersionUID = 9001;
protected JPanel panel;
static Click j = null;
protected JSlider jsl;
protected JTextField tf;
static final int CPS_MIN= 0;
static final int CPS_MAX= 100;
static final int CPS_INIT= 25;
private int amount;
private boolean visible;
public int getDelay() {
return Math.abs(jsl.getValue()-100);
}
public int getAmount() {
return amount;
}
public boolean getVisible() {
return visible;
}
public void setOpen(boolean visible) {
this.visible=visible;
}
public Clicker(boolean visible) {
buildGUI(visible);
j = new Click(false).addPosition(new Point((Toolkit.getDefaultToolkit().getScreenSize().width)/2, (Toolkit.getDefaultToolkit().getScreenSize().height)/2)).addPosition(new Point(getLocation().x+1, getLocation().y+20));
while(true) {
j.runClicks(getDelay());
}
}
public Clicker() {
buildGUI(true);
j = new Click(false).addPosition(new Point((Toolkit.getDefaultToolkit().getScreenSize().width)/2, (Toolkit.getDefaultToolkit().getScreenSize().height)/2)).addPosition(new Point(getLocation().x+1, getLocation().y+20));
while(true) {
j.runClicks(getDelay());
}
}
public void buildGUI(boolean visible) {
setTitle("Clicker");
setSize(340, 200);
setLayout(new GridLayout());
setAlwaysOnTop(true);
setLocation(0, 0);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setVisible(visible);
final JButton bt1 = new JButton("Schließen");
bt1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
final JButton bt2 = new JButton("Start ");
bt2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
j.setClick(true);
}
});
final JButton bt3 = new JButton("Stop ");
bt3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
j.setClick(false);
JOptionPane.showMessageDialog(null, "Klicken gestoppt. Klicks: " + j.getClickAmount());
j.setClickAmout(0);
}
});
final JButton bt4 = new JButton("StartAnzahl");
bt4.addActionListener(new ActionListener() {
private int amount;
public void actionPerformed(ActionEvent e) {
String wert = tf.getText();
try {
amount = Integer.parseInt(wert);
}catch(Exception ee) {
JOptionPane.showMessageDialog(null,"Das war keine Zahl oder mehr als ein Integer");
}
j.doClick(amount);
}
});
tf = new JTextField("Anzahl gewünschte Clicks max "+ Integer.MAX_VALUE, 10);
tf.setEditable(true);
jsl = new JSlider(JSlider.HORIZONTAL,CPS_MIN,CPS_MAX,CPS_INIT);
jsl.setMinorTickSpacing(5);
jsl.setMajorTickSpacing(10);
jsl.setPaintTicks(true);
jsl.setPaintLabels(true);
panel = new JPanel();
panel.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent event) {
j.setClick(false);
}
@Override
public void mouseMoved(MouseEvent event) {
j.setClick(false);
}
});
panel.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_F1) {
j.setClick(true);
}
if(e.getKeyCode() == KeyEvent.VK_F2) {
j.setClick(false);
}
}
});
add(panel);
add(bt2);
add(bt3);
add(bt1);
add(bt4);
add(jsl);
add(tf);
pack();
}
}
尝试在构造函数的末尾使用 repaint()
或 revalidate()
。并尝试在最后调用 setVisible(true)
。
让 setVisible
成为你最后一次打电话...
public void buildGUI1() throws NullPointerException {
setTitle("Hauptmenü");
setSize(800, 480);
setLayout(new GridLayout());
setAlwaysOnTop(false);
setLocation((Toolkit.getDefaultToolkit().getScreenSize().width) / 4, (Toolkit.getDefaultToolkit().getScreenSize().height) / 4);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
final JButton startclickbt = new JButton("Start Clicker");
startclickbt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
if (klick == null) {
klick = new Clicker();
add(klick);
// Add this when you need to add/remove components
revalidate();
repaint();
}
}
});
add(startclickbt);
// Move to here
setVisible(true);
}
此外,使用 revalidate()
和 repaint()
鼓励容器在添加新组件时更新其布局
建议:
- 确保您的 UI 是在 EDT 的上下文中启动的,有关详细信息,请参阅 Initial Threads
- 避免直接从像
JFrame
这样的顶级容器扩展,而是考虑使用JPanel
作为基础容器。这使您 UI 可以自由使用更广泛的用例,并防止您陷入困境(因为您无法将框架添加到其他框架) - The Use of Multiple JFrames, Good/Bad Practice?
已更新
您有两个紧迫的问题
Clicker
从JFrame
扩展,但您正试图将其添加到另一个容器,这在 Swing 中是不可能的,并且会导致异常,但是...- 您正在使用
while (true)
循环阻塞事件调度线程,这意味着 Swing 无法处理任何新事件,包括repaint
个事件
例如...
public Clicker(boolean visible) {
buildGUI(visible);
j = new Click(false).addPosition(new Point((Toolkit.getDefaultToolkit().getScreenSize().width) / 2, (Toolkit.getDefaultToolkit().getScreenSize().height) / 2)).addPosition(new Point(getLocation().x + 1, getLocation().y + 20));
// This is bad
while (true) {
j.runClicks(getDelay());
}
}
public Clicker() {
buildGUI(true);
j = new Click(false).addPosition(new Point((Toolkit.getDefaultToolkit().getScreenSize().width) / 2, (Toolkit.getDefaultToolkit().getScreenSize().height) / 2)).addPosition(new Point(getLocation().x + 1, getLocation().y + 20));
// This is bad
while (true) {
j.runClicks(getDelay());
}
}
现在,Click
看起来像是 UI 组件,它带来了很多其他问题,但我们没有相关代码,因此无法发表评论。
直接的解决方案可能是使用:
SwingWorker
,请参阅 Worker Threads and SwingWorker 了解更多详情摆动
Timer
,请参阅 How to use Swing Timers 了解更多详情- 普通老
Thread
要记住的事情
- Swing(与大多数 UI 框架一样)是单线程的,任何阻塞该线程的东西(例如永无止境的循环)都会阻止它处理新事件,包括绘制事件,这将使您的应用程序看起来喜欢它是 "hung",因为它有
- Swing 不是线程安全的。所有与 UI 的交互都必须在事件调度线程的上下文中进行。
SwingWorker
和 SwingTimer
都提供了安全更新 UI 的能力。