-->

如何重绘的东西我的JFrame时恢复(取消图标化)?(How do I redraw things

2019-11-02 05:32发布

我有JToggleButtons和子类JPanels知道如何画我希望他们能得出什么一个很基本的一点的JFrame。 选择按钮使椭圆出现在相应的面板。 取消选择按钮使得附图消失。

不幸的是,最小化(图标化),然后恢复(deiconifying)导致任何绘制的形状消失。 所以,我需要手动触发redrawings。 问题是,我只能把工作重新划分(即,我只看到它),如果我第一次显示一个消息框。

下面是对JFrame的deiconify事件:

private void formWindowDeiconified(java.awt.event.WindowEvent evt)
{                                       
    //having this message makes everything work
    JOptionPane.showMessageDialog(null, "Useless message this is.");
    //but if I skip it, I'm SOL
    //what's going on?
    drawAll();
}

这种方法越过我所有的按钮,并要求必要时重绘:

public void drawAll()
{
    for (int i=0; i<channels; i++)
    {
        if (buttons[i].isSelected())
        {
            lightboxes[i].drawMe();            
        }
    }
}

这里是我的子类的JPanel:

class MyJPanel extends JPanel {

    public void drawMe()
    {
        Graphics myGraphics = this.getGraphics();
        myGraphics.fillOval(0, 0, this.getWidth(), this.getHeight());    
    }

    public void unDraw()
    {
        this.invalidate();
        this.repaint();
    }
}

Answer 1:

首先,速度我会使用双缓冲。 这是最好的画图形关闭屏幕,并将其显示在屏幕上时,图纸已完成。 下面应该整理你。

public class MyPanel extends JPanel {
    private BufferedImage buffer;
    private Graphics2D canvas;

    @Override
    public void paintComponent(Graphics g) {
        if(buffer == null) {
            buffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
            canvas = buffer.createGraphics();
        }
        canvas.fillOval(0, 0, this.getWidth(), this.getHeight());
        g.drawImage(buffer, 0, 0, this);
    }
}


Answer 2:

一旦被还原的窗口会自动重新绘制RepaintManager 。 问题是你不喜欢你应该执行自画...

这是不是如何做定制画...

public void drawMe()
{
    Graphics myGraphics = this.getGraphics();
    myGraphics.fillOval(0, 0, this.getWidth(), this.getHeight());    
}

getGraphics可以返回null ,并且是在最好的图形状态的快照。

绘画在Swing可以随时为许多不同的原因,其中大部分你没有控制权(也不应该关心)发生。

你的工作是简单地应对这些重绘请求和更新组件的状态。

Swing也被自动调用,哪些是你可以使用一个详细的油漆链。

你应该是压倒一切paintComponent并在此方法中执行所有绘画

看看演出风俗画和在绘画AWT和Swing了解更多详情



Answer 3:

我只是提供这个答案,使人们可以看到我落得这样做。 主要的教训指出,受到大家的是使用组件的paintComponent。 见,你可能会遇到的问题自己的意见。

编辑:更新,以反映MadProgrammer意见。

//with help from Slihp and MadProgrammer on StackOverflow
//http://stackoverflow.com/q/17331986/1736461
class MyJPanel extends JPanel {

    private boolean buttonSelected = false;

    @Override
    public void paintComponent(Graphics g) {
        //make sure the background gets painted (wacky results otherwise)        
        super.paintComponent(g);

        //now if the corresponding toggle button is on, plop on the circle
        if (buttonSelected)
        {
            g.fillOval(0, 0, this.getWidth(), this.getHeight());
        }        
    }

    //an action listener for the button calls this
    public void setButtonSelected(boolean buttonStateIn)
    {
        buttonSelected = buttonStateIn;    
    }
}

我子类的按钮太多,所以我可以从事件处理程序获得它的“身份证”关闭它:

class MyJToggleButton extends JToggleButton
{       
    private int whoAmI;

    public MyJToggleButton(int whoAmIn)
    {
        //the string given to the constructor becomes the button's label
        //("1", "2", "3", etc..)
        super(Integer.toString(whoAmIn + 1));
        whoAmI = whoAmIn;      
    }

    public int getWho()
    {
        return whoAmI;
    }
}

JFrame中的代码,使按钮:

private void makeButtons(int howMany)
    {
        buttons = new MyJToggleButton[howMany];
        for (int i=0; i<howMany; i++)
        {
            buttons[i] = new MyJToggleButton(i);
            buttons[i].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent evt) {   
                    //find out which button this is
                    MyJToggleButton button = (MyJToggleButton) evt.getSource();
                    int which = button.getWho();
                    //send the button state to the corresponding lightbox
                    lightboxes[which].setButtonSelected(button.isSelected());
                    //trigger its redrawing
                    lightboxes[which].invalidate();
                    lightboxes[which].repaint();
                }
            });
            this.add(buttons[i]);
        }
    }

而这唯一的手动重绘我必须做的 - 调整大小和reshowing和所有其他有趣的事情最终还是撞了上去的paintComponent,它只是要知道,如果它的按钮被按下知道该怎么做。 超级干净,正是我想要的。



文章来源: How do I redraw things when my JFrame is restored (deiconified)?