1

正如标题所说,我很难在 JApplet 中绘制一些矩形(填充)。确切的目标是拥有一个 50x50 的表格,当您单击目标单元格时,将其填充(可能通过绘制一个填充的矩形来完成)。我已经完成了关于起点坐标的数学计算,但由于某种原因,我无法在 MouseClicked 方法中绘制新矩形。有什么建议么?

public class Main extends JApplet {

public static final int DIMX = 800;
public static final int DIMY = 800;
public static final int ratio = 16;
Graphics g;
boolean drawing;
public int cX;
public int cY;

public Main() {
    JPanel MainFrame = new JPanel();
    MainFrame.setPreferredSize(new Dimension(400, 800));
    MainFrame.setBackground(Color.LIGHT_GRAY);
    JPanel Table = new JPanel();
    Table.setPreferredSize(new Dimension(800, 800));
    Table.setBackground(Color.LIGHT_GRAY);
    add(MainFrame, BorderLayout.EAST);
    add(Table, BorderLayout.WEST);
    addMouseListener(new clicked());
}



public void paint(Graphics g) {
    super.paintComponents(g);
    g.setColor(Color.black);
    for (int i = 0; i <= 800; i += 16) {
        g.drawLine(0, i, 800, i);
        g.drawLine(i, 0, i, 800);
//            g.fillRect(cX, cY, 16, 16);
    }
}

public static void main(String[] args) {
    JFrame win = new JFrame("Retarded Bullshit");
    win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    win.setPreferredSize(new Dimension(1216, 840));
    win.setContentPane(new Main());
    win.pack();
    win.setVisible(true);

}

public class clicked extends JApplet implements MouseListener {

public int cX;
public int cY;
Graphics g;

@Override
public void mouseClicked(MouseEvent e) {
//            Point a = e.getLocationOnScreen();
    int cellX = e.getX();
    int cellY = e.getY();
    if (cellX < 800 && cellX > 0 && cellY < 800 && cellY > 0) {
        cX = cellX / 16 + 1;
        cY = cellY / 16 + 1;

        JOptionPane.showMessageDialog(null, "" + cX + " " + cY);
    }
4

2 回答 2

5

这是一个相对简单的概念(无意冒犯)。

首先,不要将您的代码与JAppletand混合使用JFrame。如果您想在这两种媒介中使用您的应用程序,请将逻辑分离到一个单独的组件(如JPanel)中,您可以轻松地将其添加到其中。您真的不应该将顶级容器添加到另一个顶级容器(将小程序添加到框架) - 这很混乱。

避免覆盖paint顶级容器的方法(如JApplet),而是使用自定义组件(如JPanel)并覆盖它的paintComponent方法。

在您的示例中,您应该打电话super.paint而不是super.paintComponents. paint做重要的工作,你不想跳过它 - 但你应该使用JComponent#paintComponent

MouseListeners 应该添加到您对管理鼠标事件感兴趣的组件中。因为clicked从未添加到任何容器中,所以它永远不会收到鼠标事件。

看一眼

在此处输入图像描述

public class SimplePaint03 {

    public static void main(String[] args) {
        new SimplePaint03();
    }

    public SimplePaint03() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new PaintPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class PaintPane extends JPanel {

        private List<Shape> grid;
        private List<Shape> fill;

        public PaintPane() {
            grid = new ArrayList<>(5);
            fill = new ArrayList<>(5);
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    for (Shape shape : grid) {
                        if (shape.contains(e.getPoint())) {
                            if (fill.contains(shape)) {
                                fill.remove(shape);
                            } else {
                                fill.add(shape);
                            }
                        }
                    }
                    repaint();
                }
            });

            int colWidth = 200 / 50;
            int rowHeight = 200 / 50;

            for (int row = 0; row < 50; row++) {
                for (int col = 0; col < 50; col++) {
                    grid.add(new Rectangle(colWidth * col, rowHeight * row, colWidth, rowHeight));
                }
            }

        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); 
            Graphics2D g2d = (Graphics2D) g;
            g2d.setColor(Color.RED);
            for (Shape cell : fill) {
                g2d.fill(cell);
            }
            g2d.setColor(Color.BLACK);
            for (Shape cell : grid) {
                g2d.draw(cell);
            }
        }

    }

}

额外的

不维护从一个油漆周期到另一个油漆周期的信息。您需要完全按照您希望它出现的方式重新绘制组件。这意味着您需要维护一个可以随时重新绘制的点击点列表。

于 2013-02-07T01:44:46.310 回答
2

从阅读自定义绘画的 Swing 教程开始。

自定义绘画是通过覆盖 JPanel 或 JComponent() 的 paintComponent() 方法来完成的。然后将面板添加到 JApplet。

如果您只想绘制某些正方形,那么您将需要一个列表来跟踪要绘制的单元格。然后每次重新绘制组件时,您都需要遍历列表并绘制单元格。

您的 MouseListener 不会扩展 JApplet。当您单击一个单元格时,您将从上方更新列表以指示需要绘制该单元格。然后您将在面板上调用 repaint() 以便调用您的绘画代码。

您可能还想查看自定义绘画方法,它根据您的确切要求提供了两种不同的方法来进行此类绘画。

于 2013-02-07T01:44:59.213 回答