0

JPanelから拡張されたクラスがあります。これがコードです。

public class DrawingPanel extends JPanel{
    DrawingPanel(){
        mouseHandler=new MouseHandler(this);
        addMouseListener(mouseHandler);
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Point=mouseHandler.getPoint();
        g2 = (Graphics2D) g;
        if (Point!=null){
            drawStartPoint(Point.getX(),Point.getY());
        }
        drawField();
    }
    private void drawField(){
        g2.setColor(Color.BLACK);
        g2.setStroke(new BasicStroke(2));
        for (int i=1;i<Main.COLUMNS;i++){
            g2.draw(new Line2D.Double(15*i,0,15*i,450));
        }
        for (int i=1;i<Main.ROWS;i++){
            g2.draw(new Line2D.Double(0,15*i,450,15*i));
        }
    }
    private void drawStartPoint(double x, double y){
        g2.setStroke(new BasicStroke((5)));
        DrawingPoint point=new DrawingPoint(Point.getX(),Point.getY());
        startPoint=new Point2D.Double(point.getX(),point.getY());
        Ellipse2D circlePoint= new Ellipse2D.Double(point.getX(),point.getY(),Main.DIAMETR_OF_CIRCLE,Main.DIAMETR_OF_CIRCLE);
        g2.fill(circlePoint);
        g2.draw(circlePoint);
    }
    public void drawDirectLineUp(){
        startPointsList.add(startPoint);
        finishPointsList.add(new Point2D.Double(startPoint.getX(),startPoint.getY()-15));
    }
    private ArrayList<Point2D> startPointsList=new ArrayList<Point2D>();
    private ArrayList<Point2D> finishPointsList=new ArrayList<Point2D>();
    private Graphics2D g2;
    private MouseHandler mouseHandler;
    private Point2D Point;
    private Point2D startPoint;
}

パネルは毎回再描画されるので、クリックします。これは mouseHandler クラスのコードです。

public class MouseHandler implements MouseListener
{
    MouseHandler(DrawingPanel thePanel)
    {
        this.panel=thePanel;
    }
    public void mouseClicked(MouseEvent event)
    {
        Point=event.getPoint();
        panel.repaint();
    }

//Here is some auto-generated methods.
    public Point2D getPoint()
    {
        Point2D thePoint=this.Point;
        this.Point=null;
        return thePoint;
    }
    private Point2D Point;
    private DrawingPanel panel;
}

ご覧のとおり、パネルをクリックするたびに、paintComponent メソッドが呼び出され、startPoint フィールドが何らかの値を取得する drawStartPoint メソッドが呼び出されます。しかし、メインパネルに配置されたボタンの actionListener から drawDirectLineUp メソッドを呼び出すと、startPoint が null になります。なぜ再びnull値になるのですか? どうすれば回避できますか?

public class MainForm{
    MainForm(){
        createUIComponents();
        //adding items to comboBoxes
        directLineOkButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0)
            {
                switch (directDirectionCombobox.getSelectedIndex()){
                    case 0: ((DrawingPanel)drawingPanel).drawDirectLineUp();  break;
                    case 1: ((DrawingPanel)drawingPanel).drawDirectLineUp();  break;
                    case 2: ((DrawingPanel)drawingPanel).drawDirectLineUp();  break;
                    case 3: ((DrawingPanel)drawingPanel).drawDirectLineUp();  break;
                }
            }
        });
    }
    public JPanel getMainPanel() {
        return mainPanel;
    }
    private void createUIComponents() {
           drawingPanel = new DrawingPanel();
    }
    private JPanel mainPanel;
    private JComboBox directDirectionCombobox;
    private JButton directLineOkButton;
    private JButton crossLineOkButton;
    private JComboBox crossLineComboBox;
    private JTextField crossLineSizeValue;
    private JButton clearButton;
    private JLabel directLineLabel;
    private JPanel directLinePanel;
    private JLabel crossLineLabel;
    private JPanel crossLinePanel;
    private JPanel okClearButtonPanel;
    private JTextField directLineSizeValue;
    private JButton saveButton;
    private JPanel drawingPanel;
}

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Main Form");
        frame.setContentPane(new MainForm().getMainPanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
    public static final int ROWS=31;
    public static final int COLUMNS=31;
    public static final int DIAMETR_OF_CIRCLE=3;
}

例外のスタック トレースを次に示します。

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at DrawingPanel.drawDirectLineUp(DrawingPanel.java:57)
    at MainForm$1.actionPerformed(MainForm.java:28)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
    at java.awt.Component.processMouseEvent(Component.java:6414)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3275)
    at java.awt.Component.processEvent(Component.java:6179)
    at java.awt.Container.processEvent(Container.java:2083)
    at java.awt.Component.dispatchEventImpl(Component.java:4776)
    at java.awt.Container.dispatchEventImpl(Container.java:2141)
    at java.awt.Component.dispatchEvent(Component.java:4604)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4619)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4280)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4210)
    at java.awt.Container.dispatchEventImpl(Container.java:2127)
    at java.awt.Window.dispatchEventImpl(Window.java:2489)
    at java.awt.Component.dispatchEvent(Component.java:4604)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:717)
    at java.awt.EventQueue.access$400(EventQueue.java:82)
    at java.awt.EventQueue$2.run(EventQueue.java:676)
    at java.awt.EventQueue$2.run(EventQueue.java:674)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:690)
    at java.awt.EventQueue$3.run(EventQueue.java:688)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:687)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

最後に、.form XML ファイルを追加します。

?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="MainForm">
  <grid id="27dc6" binding="mainPanel" layout-manager="FormLayout">
    <rowspec value="center:23px:noGrow"/>
    <rowspec value="top:3dlu:noGrow"/>
    <rowspec value="center:47px:noGrow"/>
    <rowspec value="top:3dlu:noGrow"/>
    <rowspec value="center:max(d;4px):noGrow"/>
    <rowspec value="top:3dlu:noGrow"/>
    <rowspec value="center:max(d;4px):noGrow"/>
    <rowspec value="top:7dlu:noGrow"/>
    <rowspec value="center:25px:noGrow"/>
    <rowspec value="top:174dlu:noGrow"/>
    <rowspec value="center:max(d;4px):noGrow"/>
    <colspec value="fill:d:noGrow"/>
    <colspec value="left:4dlu:noGrow"/>
    <colspec value="fill:452px:noGrow"/>
    <constraints>
      <xy x="20" y="20" width="741" height="453"/>
    </constraints>
    <properties/>
    <border type="none"/>
    <children>
      <component id="3b663" class="javax.swing.JLabel" binding="directLineLabel">
        <constraints>
          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
          <forms/>
        </constraints>
        <properties>
          <text value="Direct Line"/>
        </properties>
      </component>
      <grid id="499e0" binding="directLinePanel" layout-manager="FormLayout">
        <rowspec value="center:d:grow"/>
        <colspec value="fill:98px:noGrow"/>
        <colspec value="left:4dlu:noGrow"/>
        <colspec value="fill:80px:grow"/>
        <colspec value="left:4dlu:noGrow"/>
        <colspec value="fill:max(d;4px):noGrow"/>
        <colspec value="left:4dlu:noGrow"/>
        <colspec value="fill:max(d;4px):noGrow"/>
        <constraints>
          <grid row="1" column="0" row-span="2" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
          <forms/>
        </constraints>
        <properties/>
        <border type="none"/>
        <children>
          <component id="c383d" class="javax.swing.JComboBox" binding="directDirectionCombobox">
            <constraints>
              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
              <forms/>
            </constraints>
            <properties>
              <enabled value="true"/>
            </properties>
          </component>
          <component id="17aa1" class="javax.swing.JTextField" binding="directLineSizeValue">
            <constraints>
              <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
                <preferred-size width="150" height="-1"/>
              </grid>
              <forms defaultalign-horz="false"/>
            </constraints>
            <properties/>
          </component>
          <component id="44fc7" class="javax.swing.JButton" binding="directLineOkButton">
            <constraints>
              <grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
              <forms/>
            </constraints>
            <properties>
              <text value="OK"/>
            </properties>
          </component>
        </children>
      </grid>
      <component id="5a571" class="javax.swing.JLabel" binding="crossLineLabel">
        <constraints>
          <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
          <forms/>
        </constraints>
        <properties>
          <text value="Cross Line"/>
        </properties>
      </component>
      <grid id="77f1a" binding="crossLinePanel" layout-manager="FormLayout">
        <rowspec value="center:d:grow"/>
        <colspec value="fill:98px:noGrow"/>
        <colspec value="left:4dlu:noGrow"/>
        <colspec value="fill:80px:grow"/>
        <colspec value="left:4dlu:noGrow"/>
        <colspec value="fill:max(d;4px):noGrow"/>
        <colspec value="left:4dlu:noGrow"/>
        <colspec value="fill:max(d;4px):noGrow"/>
        <constraints>
          <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
          <forms/>
        </constraints>
        <properties/>
        <border type="none"/>
        <children>
          <component id="32368" class="javax.swing.JComboBox" binding="crossLineComboBox">
            <constraints>
              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
              <forms/>
            </constraints>
            <properties/>
          </component>
          <component id="dbf23" class="javax.swing.JTextField" binding="crossLineSizeValue">
            <constraints>
              <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
                <preferred-size width="150" height="-1"/>
              </grid>
              <forms defaultalign-horz="false"/>
            </constraints>
            <properties/>
          </component>
          <component id="c5c8a" class="javax.swing.JButton" binding="crossLineOkButton">
            <constraints>
              <grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
              <forms/>
            </constraints>
            <properties>
              <text value="OK"/>
            </properties>
          </component>
        </children>
      </grid>
      <grid id="53bbc" binding="okClearButtonPanel" layout-manager="FormLayout">
        <rowspec value="center:d:noGrow"/>
        <colspec value="fill:d:noGrow"/>
        <colspec value="left:4dlu:noGrow"/>
        <colspec value="fill:max(d;4px):noGrow"/>
        <constraints>
          <grid row="8" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
          <forms/>
        </constraints>
        <properties>
          <enabled value="false"/>
        </properties>
        <border type="none"/>
        <children>
          <component id="41ba7" class="javax.swing.JButton" binding="saveButton">
            <constraints>
              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
              <forms/>
            </constraints>
            <properties>
              <text value="Save"/>
            </properties>
          </component>
          <component id="a6bf6" class="javax.swing.JButton" binding="clearButton">
            <constraints>
              <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
              <forms/>
            </constraints>
            <properties>
              <text value="Clear"/>
            </properties>
          </component>
        </children>
      </grid>
      <grid id="2e94e" binding="drawingPanel" custom-create="true" layout-manager="FormLayout">
        <rowspec value="center:d:grow"/>
        <colspec value="fill:d:grow"/>
        <constraints>
          <grid row="0" column="2" row-span="11" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
          <forms/>
        </constraints>
        <properties>
          <background color="-1"/>
        </properties>
        <border type="none"/>
        <children/>
      </grid>
    </children>
  </grid>
</form>

奇妙なバグ

4

4 に答える 4

1

インスタンス化の問題のように見えますが、DrawingPanel2 回作成されました。また、メソッドcreateUIComponentsは 2 回呼び出されました。1 回はコンストラクター内で、もう 1 回はMainForm.form(標準メソッドまたはこのようなもののように見えます) によって呼び出されたため、2 つの別個のインスタンスがありました。

解決策は冗長なcreateUIComponents呼び出しを削除することです

于 2013-09-24T08:40:09.090 に答える
0

ボタンの ActionListener の変数 drawingPanel が、クリックした同じ DrawingPanel を指していない可能性はありますか?

そして、パネルをクリックする前に最初にボタンをクリックした場合、変数 startPoint はまだ null のままです。

于 2013-09-23T10:32:08.157 に答える