无法将paintComponent面板添加到框架中。

4

我遇到了在将一个包含paintComponent的JPanel添加到JFrame时的问题。
如果这是我添加到框架的唯一组件,则可以正常工作。但是,一旦我添加了布局管理器并向JFrame添加其他组件,它就不再显示具有绘画的面板!

为了更清晰地说明...

以下是代码,只有添加JPanel,成功显示出来:

绘制标记的面板(实际上我并非试图绘制“hello”,这只是为了简化此处的代码)

public class SignPanel2 extends JPanel {
public int hello;

public void paintComponent(Graphics comp) {
    Graphics g = (Graphics) comp;
    g.setColor(Color.LIGHT_GRAY);
    g.fillRect(70, 250, 150, 150);

    g.setColor(Color.BLACK); 

    if (hello > 0) 
        g.drawString("h",135, 270);

    if (hello > 1 ) 
        g.drawString("h e",135, 270);

    if (hello > 2) 
        g.drawString("h e l",135, 270);

    if (hello > 3) 
        g.drawString("h e l l",135, 270);

    if (hello > 4) 
        g.drawString("h e l l o",135, 270);
}

}

我把面板放在的框架:
public class SignFrame extends JFrame {

// the constructor method
public SignFrame () {

    super("This is the title of the Sign Frame");
    setSize(300,500);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // make a container for the frame
    Container content = getContentPane();

    // call from the drawing panel
    SignPanel2 signpanel = new SignPanel2();
    // change class variable of SignPanel
    signpanel.hello = 5;
    signpanel.repaint();


    // add signpanel to container
    content.add(signpanel);

    setContentPane(content);

    setVisible(true);

}

}

主要类
public class TheSignMain {

public static void main (String[] args) {

    SignFrame signframe = new SignFrame();

}

}

上面的代码完美运行并给出了一个包含所需绘图的框架。但是如果我向框架添加其他组件并添加布局管理器,则不再显示绘画,即使使用repaint()也无效。
我必须包括一个布局管理器,否则它会添加带有绘画的面板,但不包括其他组件。

这是我的框架类现在的样子,也是我遇到问题的地方:

public class SignFrame extends JFrame {

// the constructor method
public SignFrame () {

    super("This is the title of the Sign Frame");
    setSize(300,500);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // make a container for the frame
    Container content = getContentPane();


    // need a layout manager to decide the arrangement of the components on the container
    FlowLayout flo = new FlowLayout();
    // designate the layout manager to the container
    content.setLayout(flo);


    // make components
    JPanel buttons = new JPanel();
    JButton play = new JButton("Play");
    JButton pause = new JButton("Pause");
    JButton stop = new JButton("Stop");
    // add components to a panel
    buttons.add(play);
    buttons.add(pause);
    buttons.add(stop);
    // add panel to frame container
    content.add(buttons);


    // call from the drawing panel
    SignPanel2 signpanel = new SignPanel2();
    // change class variable of SignPanel
    signpanel.hello = 5;
    signpanel.repaint();


    // add signpanel to container
    content.add(signpanel);

    setContentPane(content);

    setVisible(true);

}

}

我完全是Java的新手,所以非常感谢您的帮助。 对于所有的代码混乱,感到抱歉并感谢您的帮助!


1
+1,不错的问题。让我今天学到了东西 :-) - nIcE cOw
@Gagandeep...我不确定我对你的回答做了什么。我点击了JB Nizet旁边的勾号图标,将其设置为被接受的答案(即解决了问题),但是然后你的回复消失了。我没有想到它会删除其他回复。我很抱歉,我今天才注册,所以我对论坛的运作方式还不熟悉。 - phy2sma
那是我故意删除的。因为你想要的和JB Nizet告诉你的都很好。保持微笑,没什么可担心的 :-) - nIcE cOw
你是否遇到了同样的问题?上次没有解决的问题,请具体说明。 - nIcE cOw
1个回答

4

尚未经过测试,但流动布局可能使用面板的首选大小,而您可能尚未覆盖getPreferredSize()以返回除[0,0]尺寸以外的其他内容。

此外,您应该在一个setHello()方法中封装hello变量的更改,并调用repaint()。调用代码不应处理重绘。面板应该知道何时需要重绘,并调用repaint自己。


实际上我刚试着编写了这段代码,但是它报错说:“类型SignPanel2未定义方法getPrefferedSize()”。 - phy2sma
该方法名为getPreferredSize(),不需要任何参数。您必须在自定义面板(SignPanel2)中实现它,并且它必须覆盖JComponent的getPreferredSize()方法:http://docs.oracle.com/javase/6/docs/api/javax/swing/JComponent.html#getPreferredSize%28%29 - JB Nizet
这是我添加的...signpanel.getPrefferedSize(); - phy2sma
1
@phy2sma:根据JB Nizet的写法,他的意思是你的SignPanel2类必须定义getPreferredSize()方法,就像你重写paintComponent()方法一样,在同一个类中。只需使该方法返回类似于return new Dimension(300, 500);的内容即可。 - nIcE cOw
好的。谢谢你的帮助。现在我已经在我的SignPanel中有了getPreferredSize()方法,并且它会在paintComponent中绘制出来。 现在我正在尝试处理hello变量的方法。 - phy2sma
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接