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

これは比較的単純な概念です (問題はありません)。

まず、コードに と を混在させないでJAppletくださいJFrame。これら 2 つの媒体でアプリケーションを使用する場合は、ロジックを別のコンポーネント ( などJPanel) に分割し、どちらにも簡単に追加できます。トップ レベル コンテナを別のトップ レベル コンテナに追加する (フレームにアプレットを追加する) べきではありません。面倒です。

paint最上位コンテナーのメソッド ( など) をオーバーライドするのは避けJApplet、代わりにカスタム コンポーネント ( などJPanel) を使用して、そのpaintComponentメソッドをオーバーライドします。

あなたの例では、super.paintではなく呼び出す必要がありますsuper.paintComponentspaint重要な作業を行います。スキップしたくありませんが、使用する必要がありますJComponent#paintComponent

MouseListenerは、マウス イベントの管理に関心のあるコンポーネントに追加する必要があります。はどのコンテナにも追加されないため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() を呼び出して、ペイント コードが呼び出されるようにします。

また、正確な要件に応じて、このタイプのペインティングを行うための 2 つの異なる方法を提供するカスタム ペインティング アプローチも参照してください。

于 2013-02-07T01:44:59.213 に答える