Почему моя краска JComponent (Графика g) не работает / не вызывается? - PullRequest
0 голосов
/ 09 июня 2018

Я пытался закодировать это приложение, которое создает полигоны с точками.Когда я попытался запустить его сначала, я подумал, что есть проблема с моими очками.Но когда я начал возиться, искать проблему, я понял, что мой метод рисования в JComponent даже не вызывается.Что я должен сделать, чтобы это исправить?

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JToggleButton;

public class PolygonBuilder extends JFrame{

    final static int WIDTH = 1280;
    final static int HEIGHT = 640;
    public static int xPointPos, yPointPos;
    public static void main(String[] args) {
        new PolygonBuilder();
    }
    public PolygonBuilder() {
        setTitle("Build a Polygon");
        this.setSize(WIDTH,HEIGHT);
        setResizable(false);
        JLabel placeholder = new JLabel();
        BuilderDrawingPanel BuilderPanel = new BuilderDrawingPanel();
        this.add(BuilderPanel, BorderLayout.CENTER);

        JToggleButton DotOnOff = new JToggleButton("Dot");
        DotOnOff.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent arg0) {
                // TODO Auto-generated method stub
                if(DotOnOff.isSelected()) {
                    System.out.println("ON");
                } else {
                    System.out.println("OFF");
                }
            }
        });

        DotOnOff.setBounds(100, 100, 90, 35);

        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5);
        executor.scheduleAtFixedRate(new RepaintTheBoard(this), 0L, 20L, TimeUnit.MILLISECONDS);

        addMouseMotionListener(new MouseMotionListener() {
            @Override
            public void mouseDragged(MouseEvent arg0) {}

            @Override
            public void mouseMoved(MouseEvent arg0) {
                Point p = MouseInfo.getPointerInfo().getLocation();
                xPointPos = (int) p.getX();
                yPointPos = (int) p.getY();
                System.out.println(xPointPos+","+yPointPos);
            }
        });

        this.add(DotOnOff);
        this.add(placeholder);
        setVisible(true);
    }
}
class RepaintTheBoard implements Runnable {
    PolygonBuilder theBuilder;

    public RepaintTheBoard(PolygonBuilder theBuilder) {
        this.theBuilder = theBuilder;
    }

    @Override
    public void run() {
        theBuilder.repaint();
    }
}

@SuppressWarnings("serial")
class BuilderDrawingPanel extends JComponent{
    static Graphics2D graphicSettings;
    static Shape drawLine;
    public BuilderDrawingPanel() {
        //stuff to draw at start
        System.out.println("Drawing..");
        drawLine =  new Line2D.Float(480,480,0,0);
    }
    @Override
    public void paint(Graphics g) {

        graphicSettings = (Graphics2D)g;
        System.out.println("Drawing..");
        graphicSettings.setColor(Color.RED);
        graphicSettings.fillRect(0, 0, getWidth(), getHeight());
        graphicSettings.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        graphicSettings.setPaint(Color.BLUE);
        graphicSettings.draw(drawLine);
    }
}

1 Ответ

0 голосов
/ 09 июня 2018

Хотя c0der предоставил некоторую ценную информацию и ссылки, я чувствую, что есть некоторые аспекты этого, которые должны быть рассмотрены в ответе.

  • Макет по умолчанию (панель содержимого) a JFrame является BorderLayout.
  • Любой компонент, добавленный к макету границы без ограничений, по умолчанию равен CENTER.
  • Каждая область (ограничение макета) макета границы может отображать ровно однукомпонент.

Итак, мы подходим к этой части кода:

this.add(DotOnOff);
this.add(placeholder);

JVM попытается добавить их в центр панели содержимого, в которую чертеж конструктораПанель уже добавлена.Вот почему он даже не появляется (или не окрашивается).

Другие советы:

  • В любом JComponent правильный метод переопределения для пользовательской рисования - paintComponent(Graphics) метод.
  • Любой переопределенный метод рисования должен немедленно вызывать супер-метод, чтобы обеспечить закрашивание фона, границ и других «автоматических» элементов.
  • Объект Graphics является временным, поэтому не должен бытьхранится как атрибут класса и, конечно, не должен быть объявлен как static.
  • Говоря о объявлениях static, они (по крайней мере в графическом интерфейсе) чаще являются источником проблем, чем решений.Не объявляйте атрибуты GUI как статические, если вы не можете объяснить, почему это имеет смысл.
  • Пожалуйста, изучите общую номенклатуру Java (соглашения об именах - например, EachWordUpperCaseClass, firstWordLowerCaseMethod(), firstWordLowerCaseAttribute, если это не так.UPPER_CASE_CONSTANT) и используйте его последовательно.

Обновление

Это источник, показанный в вопросе, с устранением наиболее неотложной проблемы.Он не меняет большинство других рекомендуемых вещей и не затрагивает другие проблемы, которые я видел при работе с самим кодом.Посмотрите на комментарии для вещей, которые были изменены, чтобы заставить его работать.

Вот как это выглядит здесь, с изменениями:

enter image description here

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import java.util.concurrent.*;
import javax.swing.*;

public class PolygonBuilder extends JFrame{

    final static int WIDTH = 640;
    final static int HEIGHT = 320;
    public static int xPointPos, yPointPos;
    public static void main(String[] args) {
        new PolygonBuilder();
    }
    public PolygonBuilder() {
        setTitle("Build a Polygon");
        // let's be nice to the user..
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // this is almost certainly not the correct size, 
        // but in itself could deserve a question
        this.setSize(WIDTH,HEIGHT);
        setResizable(false);
        JLabel placeholder = new JLabel("Label!");
        BuilderDrawingPanel BuilderPanel = new BuilderDrawingPanel();
        this.add(BuilderPanel, BorderLayout.CENTER);

        JToggleButton DotOnOff = new JToggleButton("Dot");
        DotOnOff.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent arg0) {
                if(DotOnOff.isSelected()) {
                    System.out.println("ON");
                } else {
                    System.out.println("OFF");
                }
            }
        });

        DotOnOff.setBounds(100, 100, 90, 35);

        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5);
        executor.scheduleAtFixedRate(new RepaintTheBoard(this), 0L, 20L, TimeUnit.MILLISECONDS);

        addMouseMotionListener(new MouseMotionListener() {
            @Override
            public void mouseDragged(MouseEvent arg0) {}

            @Override
            public void mouseMoved(MouseEvent arg0) {
                Point p = MouseInfo.getPointerInfo().getLocation();
                xPointPos = (int) p.getX();
                yPointPos = (int) p.getY();
                System.out.println(xPointPos+","+yPointPos);
            }
        });

        // create a new panel for these buttons..
        //this.add(DotOnOff);
        //this.add(placeholder);
        JPanel buttonPanel = new JPanel(); // default flow layout
        buttonPanel.add(DotOnOff);
        buttonPanel.add(placeholder);
        // now add that panel above the builder panel
        this.add(buttonPanel, BorderLayout.PAGE_START);
        setVisible(true);
    }
}
class RepaintTheBoard implements Runnable {
    PolygonBuilder theBuilder;

    public RepaintTheBoard(PolygonBuilder theBuilder) {
        this.theBuilder = theBuilder;
    }

    @Override
    public void run() {
        theBuilder.repaint();
    }
}

@SuppressWarnings("serial")
class BuilderDrawingPanel extends JComponent{
    static Graphics2D graphicSettings;
    static Shape drawLine;
    public BuilderDrawingPanel() {
        //stuff to draw at start
        System.out.println("Drawing..");
        drawLine =  new Line2D.Float(480,480,0,0);
    }
    @Override
    public void paint(Graphics g) {

        graphicSettings = (Graphics2D)g;
        System.out.println("Drawing..");
        graphicSettings.setColor(Color.RED);
        graphicSettings.fillRect(0, 0, getWidth(), getHeight());
        graphicSettings.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        graphicSettings.setPaint(Color.BLUE);
        graphicSettings.draw(drawLine);
    }
}
...