簡體   English   中英

使用JPanel在按鈕上繪制矩形

[英]Painting a rectangle on a button click using JPanel

我正在嘗試使用JPanel繪制一個矩形。 問題是,當我點擊菜單項時,它應該繪制一個新的矩形。 但是,當我這樣做的時候,只畫了一部分。 這就是我的意思:

    rectangleMenuItem.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent event) {
            squares.addSquare(10, 10, 100, 100);
        }
    });

做這個:

不

但是當我把ActionListener的squares.addSquare(...) OUTSIDE放到它時,它給出了正確的形狀(只是當我想要它時)

    squares.addSquare(10, 10, 100, 100);
    rectangleMenuItem.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent event) {
            //nothing on click...
        }
    });

這是正確的矩形:

在此輸入圖像描述

任何想法,當我把它放在ActionListener中時為什么它沒有正確繪制? 謝謝。

完整代碼

class UMLWindow extends JFrame {
Squares squares = new Squares();

private static final long serialVersionUID = 1L;

public UMLWindow() {
    addMenus();
}

public void addMenus() {

    getContentPane().add(squares);
    //squares.addSquare(10, 10, 100, 100);

    JMenuBar menubar = new JMenuBar();

    JMenu file = new JMenu("File");
    file.setMnemonic(KeyEvent.VK_F);

    JMenu shapes = new JMenu("Shapes");
    file.setMnemonic(KeyEvent.VK_F);

    JMenuItem rectangleMenuItem = new JMenuItem("New Rectangle");
    rectangleMenuItem.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent event) {
            squares.addSquare(10, 10, 100, 100);
        }
    });

    shapes.add(rectangleMenuItem);

    menubar.add(shapes);

    setJMenuBar(menubar);

    setTitle("UML Editior");
    setSize(300, 200);
    setLocationRelativeTo(null);
}


}

class Squares extends JPanel {
private static final long serialVersionUID = 1L;

private List<Rectangle> squares = new ArrayList<Rectangle>();

public void addSquare(int x, int y, int width, int height) {
    Rectangle rect = new Rectangle(x, y, width, height);
    squares.add(rect);
}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    this.setOpaque(true);
    this.setBackground(Color.WHITE);
    Graphics2D g2 = (Graphics2D) g;
    for (Rectangle rect : squares) {
        g2.draw(rect);
    }
}

}

Swing使用被動渲染引擎,因此除非您告訴它,否則它不知道何時應該更新/重新繪制組件。

首先從你的addSquare方法中調用repaint ...

public void addSquare(int x, int y, int width, int height) {
    Rectangle rect = new Rectangle(x, y, width, height);
    squares.add(rect);
    repaint();
}

這將向重繪管理器發出請求,通知它需要重新繪制當前組件。

您還應該為組件提供大小調整提示,因此布局管理器將其大小設置為0x0

考慮重寫Squares類的getPreferredSize方法並返回適當的默認大小......

@Override
public Dimension getPreferredSize() {
    return new Dimension(300, 200);
}

這也意味着您可以在主窗口上調用pack ,它將在內容周圍“打包”,非常整潔。

此外,不要調用會改變組件或其他組件狀態或安排額外repaint請求的方法,因為這可能會設置無限循環的重繪,這將耗盡您的PC資源....

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    // This is bad...
    //this.setOpaque(true);
    // This is bad...
    //this.setBackground(Color.WHITE);
    Graphics2D g2 = (Graphics2D) g;
    for (Rectangle rect : squares) {
        g2.draw(rect);
    }
}

不透明度和顏色之類的東西應該在油漆循環之外定義。 此外,默認情況下,從JPanel擴展的組件是不透明的;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM