为什么JFrame没有正确添加组件

时间:2015-07-04 21:11:49

标签: java swing jframe jcomponent

尝试将组件添加到JFrame时出错。

这是第一堂课:

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class FrameG extends JFrame
{

private static final String MOVE_UP = "move up";
public static int frameID = 1;
private static JFrame window = new JFrame();
private static openWin frame = new frame01();
public static void main(String[] args) {
    window.setSize(1500,900);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setVisible(true);
    window.setResizable(true);
    frame.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), MOVE_UP);
    frame.getActionMap().put(MOVE_UP, new movement());
    mainloop();
}
private static void mainloop()
{
    window.removeAll();
    switch(frameID)
    {
        case 1:
            frame = new frame01();
            frame.setLayout(new FlowLayout());
            System.out.println(frame);
            window.add(frame);
            break;
        default:
            break;
    }
    try {
        Thread.sleep(1000);
    } catch (InterruptedException ex) {
        Logger.getLogger(FrameG.class.getName()).log(Level.SEVERE, null, ex);
    }
    mainloop();
}
}
class movement extends AbstractAction
{
@Override
public void actionPerformed(ActionEvent e) {
    System.out.println("hi");
}
}

和第二个类(它使用扩展JComponent的抽象绘制方法扩展了一个类):

import java.awt.Graphics;
import java.awt.*;
import javax.swing.JComponent;
import java.awt.geom.*;
public class frame01 extends openWin{
@Override
public void paint(Graphics g) {
    Graphics2D pic = (Graphics2D) g;
    pic.setBackground(Color.BLACK);
}
}

错误可能是无效的部分,但我不确定它是什么:

frameg.frame01[,0,0,0x0,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=0,maximumSize=,minimumSize=,preferredSize=]

3 个答案:

答案 0 :(得分:3)

您的代码显示了对Swing如何工作

的明显缺乏理解

此...

private static void mainloop()
{
    window.removeAll();
    switch(frameID)
    {
        case 1:
            frame = new frame01();
            frame.setLayout(new FlowLayout());
            System.out.println(frame);
            window.add(frame);
            break;
        default:
            break;
    }
    try {
        Thread.sleep(1000);
    } catch (InterruptedException ex) {
        Logger.getLogger(FrameG.class.getName()).log(Level.SEVERE, null, ex);
    }
    mainloop();
}

有两个原因是错误的,第一个原因是它最终会生成StackOverflowException,第二个原因是它违反了Swing的单线程规则。

通常情况下,while-loop通常会更好,但是当您处理基于Swing的组件时,您应该考虑使用Swing TimerSwingWorker,具体取决于具体内容你希望实现。

不断添加和删除组件似乎也是一个奇怪的想法,但是没有任何背景可以知道你希望实现的是什么。话虽如此,作为一般规则,如果您想在视图之间切换,CardLayout通常被认为是首选解决方案

此...

public class frame01 extends openWin{
    @Override
    public void paint(Graphics g) {
        Graphics2D pic = (Graphics2D) g;
        pic.setBackground(Color.BLACK);
    }
}

只是什么也不做,除了打破油漆链,这可能导致无法生成奇怪的油漆伪影。如果暂时改变Graphics上下文的背景颜色,你所做的所有代码都会这样做,但由于你没有用它绘制任何内容,它实际上毫无意义

作为一般规则,建议您在执行任何自定义绘制之前覆盖Swing组件的paintComponent方法(并调用super.paintComponent)。

我强烈建议你看看:

答案 1 :(得分:2)

您的代码存在很多问题。正如我在评论中所说,private static openWin frame = new frame01();这一行似乎很可疑。但这不是最糟糕的部分:

:此:

private static void mainloop()
{
    window.removeAll();
    switch(frameID)
    {
        case 1:
            frame = new frame01();
            frame.setLayout(new FlowLayout());
            System.out.println(frame);
            window.add(frame);
            break;
        default:
            break;
    }
    try {
        Thread.sleep(1000);
    } catch (InterruptedException ex) {
        Logger.getLogger(FrameG.class.getName()).log(Level.SEVERE, null, ex);
    }
    mainloop();
}

BAD !它可能会中断,因为您不断创建new frame01()并将其添加到window

同样不要覆盖paint,但paintComponent。我没有得到的另一件事是为什么要在单独的class而不是openWin本身中覆盖它。

另一件事,不要放弃主线,如果你真的必须自己运行并让IT睡觉。

此代码的目的是什么?我正在努力理解它,所以我可以帮你重新设计它。

PS:不是一个真正的答案,只是比评论长一点。

答案 2 :(得分:1)

永远不要使用线程,它作为计时器启动和停止。请改用javax.swing.Timer。此外,您还创建了一个递归函数来实现一个非常有线并且容易失败的无限循环。 Swing拥有它自己的线程,当你将它与另一个线程混合在一起时,它会在不知不觉中将你的代码转换成我们都害怕的怪物。