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>