I am making a small hobby game, I have a couple of classes so far. There are two classes that I am having some issues with, the classes in question are listed below.
Screen.Java
package geisst.flat;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class Screen extends JFrame {
public int x = 100;
public int y = 100;
public Screen() {
this.setSize(400, 400);
this.setTitle("Flat Game");
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
addKeyListener(new KeyListen());
}
public void paint(Graphics g) {
BufferedImage mainImage = null;
try {
mainImage = ImageIO.read(new File("res/test.gif"));
} catch(IOException e) {
}
g.drawImage(mainImage, x, y, null);
repaint();
}
}
And KeyListen.Java
package geisst.flat;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class KeyListen extends KeyAdapter {
Screen screen;
#Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_LEFT) {
screen.x += 3;
}
}
}
KeyListen is supposed to move the mainImage's x position up by 3 pixels, but I recieve the following error.
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at geisst.flat.KeyListen.keyPressed(KeyListen.java:15)
at java.awt.Component.processKeyEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Window.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Do you guy's and gal's have any idea why this would be happening? It's probably something really obvious :P
Thanks in advance,
GeissT
You are never initializing the value of screen.
What you can do is something like this:
In the KeyListener Class
public KeyListen (Screen screen) {
this.screen = screen;
}
and in the Screen Class:
addKeyListener(new KeyListen(this));
You never initialize screen, so it is null, and yet you use it's properties:
screen.x += 3;
You should pass a reference to the Screen object to the listener, or by calling getSource:
#Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_LEFT) {
if (e.getSource() instanceof Screen)
((Screen)e.getSource()).x += 3;
}
}
1) not good idea paint directly to the JFrame, put there JPanel, JComponent or JLabel
2) for Swing JComponents is there paintComponent instead of paint, paint is correct method for painting to the RootPane or GlassPane (derived Component from JFrame)
3) use KeyBindings rather than KeyListener, because KeyListener doesn't works without Focus in the Window, not good idea to setFocusable to the ContentPane
4) use JComponent for Custom Painting or JLabel with Icon
5) example for KeyBindings here
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I am trying to get the timer working to move the ball. It just isn't working. I am getting alot of errors which i don't yet understand
Can someone tell me what i am doing wrong.
Here is the error that i got.
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Paneel$TimerHandler.actionPerformed(Paneel.java:30)
at javax.swing.Timer.fireActionPerformed(Unknown Source)
at javax.swing.Timer$DoPostEvent.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Thanks in advance.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Paneel extends JPanel
{
private int height, width;
private boolean moveLeft, moveRight, moveUp, moveDown;
private Timer timer;
private Ball ball;
public Paneel()
{
TimerHandler timerHandler = new TimerHandler();
timer = new Timer(20, timerHandler);
timer.start();
}
public void paintComponent(Graphics pen)
{
super.paintComponent(pen);
ball = new Ball((double)getWidth(), (double)getHeight());
ball.drawBall(pen);
}
class TimerHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
ball.moveDown();
repaint();
}
}
}
You are creating a new Ball object during each paint
ball = new Ball((double)getWidth(), (double)getHeight());
That means that the ball reference is null up until the first paint call.
ball.moveDown(); // ball here could be null
I recommend defining ball in the constructor for now. I'll need to see the source of the Ball class before I can figure out how to set its size correctly.
public Paneel()
{
ball = new Ball(0, 0);
TimerHandler timerHandler = new TimerHandler();
timer = new Timer(20, timerHandler);
timer.start();
}
When executing bottomLabel.setVisible(true); I get an unresolved compilation problem:
The type Assignment1 must implement the inherited abstract method ActionListener.actionPerformed(ActionEvent)
It is like that I should create a new variable as it is not readable from the constructor. Where is my mistake? Here is the code simplified as much as possible:
public class Assignment1 extends JFrame implements ActionListener{
//declare variables
int x= 101;
int low = 0;
int high = 100;
int guess = (high + low) / 2;
int counter = 0;
private static final long serialVersionUID = 1L;
//main method
//...some code...
//constructor
public Assignment1(){
//...some code...
//declare buttons
JButton correct = new JButton("correct!");
//add buttons
//...some code...
//declare TextField and Labels
JTextField numberTextField = new JTextField(20);
JLabel topLabel = new JLabel("T");
JLabel bottomLabel = new JLabel("G");
//add TextField and Labels and position them on the layout
//...some code...
bottomLabel.setBounds(110, 300, 400, 20);
add(bottomLabel);
bottomLabel.setVisible(false);
//add ActionListener to each button
//...some code...
correct.addActionListener(this);
}
#Override
//define ActionPerformed when an Event is parsed
public void actionPerformed(ActionEvent e) {
String buttonClicked = e.getActionCommand();
if(buttonClicked.equals("Yes, correct!")){
System.out.println("correct");
bottomLabel.setVisible(true);
}
}
}
Here's the full stack trace:
at Assignment1.Assignment1.actionPerformed(Assignment1.java:12)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
bottomLabel is visible only inside the constructor, as it's not declared at class-level.
Declare it at class-level (as you did with x, low, high, etc) to make it work:
public class Assignment1 extends JFrame implements ActionListener {
// declare variables
int x = 101;
int low = 0;
int high = 100;
int guess = (high + low) / 2;
int counter = 0;
JLabel bottomLabel; // <==
public Assignment1() {
// [...] other assignments
bottomLabel = new JLabel("Game Over, your number is NN, i got it in N times. Wanna play again?");
// [...] rest of class
I have a java application where when the user presses a button, I want it to open another different application in a new window. However, the application is a programmed one in Eclipse, not one downloaded onto my computer. I have tried various things such as running threads, but to no avail. Here is the section of the class where the user pushes the button:
JButton LiveFeed = new JButton("Live Feed");
final JPanel jsr3 = new JPanel();
jsr3.add(LiveFeed);
LiveFeed.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
new KinectViewer();
}
});
jsr3.setVisible(true);
And here is the class that I am trying to open seperate from the main application:
package skeleton;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import edu.ufl.digitalworlds.gui.DWApp;
#SuppressWarnings("serial")
public class KinectViewer extends DWApp implements ChangeListener
{
Kinect myKinect;
ViewerPanel3D main_panel;
JSlider elevation_angle;
JCheckBox near_mode;
JCheckBox seated_skeleton;
JCheckBox track_skeleton;
JButton turn_off;
JComboBox depth_resolution;
JComboBox video_resolution;
JCheckBox show_video;
JCheckBox mask_players;
JLabel accelerometer;
public void GUIsetup(JPanel p_root) {
setLoadingProgress("Intitializing Kinect...",20);
myKinect=new Kinect();
if(myKinect.start(true,Kinect.NUI_IMAGE_RESOLUTION_320x240,Kinect.NUI_IMAGE_RESOLUTION_640x480)==0)
{
DWApp.showErrorDialog("ERROR", "<html><center><br>ERROR: The Kinect device could not be initialized.<br><br>1. Check if the Microsoft's Kinect SDK was succesfully installed on this computer.<br> 2. Check if the Kinect is plugged into a power outlet.<br>3. Check if the Kinect is connected to a USB port of this computer.</center>");
//System.exit(0);
}
myKinect.computeUV(true);
near_mode=new JCheckBox("Near mode");
near_mode.addActionListener(this);
seated_skeleton=new JCheckBox("Seated skeleton");
seated_skeleton.addActionListener(this);
elevation_angle=new JSlider();
elevation_angle.setMinimum(-27);
elevation_angle.setMaximum(27);
elevation_angle.setValue((int)myKinect.getElevationAngle());
elevation_angle.setToolTipText("Elevation Angle ("+elevation_angle.getValue()+" degrees)");
elevation_angle.addChangeListener(this);
turn_off=new JButton("Turn off");
turn_off.addActionListener(this);
depth_resolution=new JComboBox();
depth_resolution.addItem("80x60");
depth_resolution.addItem("320x240");
depth_resolution.addItem("640x480");
depth_resolution.setSelectedIndex(1);
depth_resolution.addActionListener(this);
video_resolution=new JComboBox();
video_resolution.addItem("640x480");
video_resolution.addItem("1280x960");
video_resolution.setSelectedIndex(0);
video_resolution.addActionListener(this);
track_skeleton=new JCheckBox("Track Skeletons");
track_skeleton.setSelected(true);
track_skeleton.addActionListener(this);
show_video=new JCheckBox("Show video");
show_video.setSelected(true);
show_video.addActionListener(this);
mask_players=new JCheckBox("Mask Players");
mask_players.setSelected(false);
mask_players.addActionListener(this);
JPanel controls=new JPanel(new GridLayout(0,6));
controls.add(new JLabel("Depth Stream:"));
controls.add(depth_resolution);
controls.add(near_mode);
controls.add(new JLabel("Video Stream:"));
controls.add(video_resolution);
controls.add(show_video);
controls.add(new JLabel("Skeleton Stream:"));
controls.add(track_skeleton);
controls.add(seated_skeleton);
controls.add(mask_players);
accelerometer=new JLabel("0,0,0");
controls.add(accelerometer);
controls.add(elevation_angle);
//controls.add(turn_off);
setLoadingProgress("Intitializing OpenGL...",60);
main_panel=new ViewerPanel3D();
myKinect.setViewer(main_panel);
myKinect.setLabel(accelerometer);
p_root.add(main_panel, BorderLayout.CENTER);
p_root.add(controls, BorderLayout.SOUTH);
System.out.print("GUIsetup");
}
public void GUIclosing()
{
myKinect.stop();
}
private void resetKinect()
{
if(turn_off.getText().compareTo("Turn on")==0) return;
myKinect.stop();
int depth_res=Kinect.NUI_IMAGE_RESOLUTION_INVALID;
if(depth_resolution.getSelectedIndex()==0) depth_res=Kinect.NUI_IMAGE_RESOLUTION_80x60;
else if(depth_resolution.getSelectedIndex()==1) depth_res=Kinect.NUI_IMAGE_RESOLUTION_320x240;
else if(depth_resolution.getSelectedIndex()==2) depth_res=Kinect.NUI_IMAGE_RESOLUTION_640x480;
int video_res=Kinect.NUI_IMAGE_RESOLUTION_INVALID;
if(video_resolution.getSelectedIndex()==0) video_res=Kinect.NUI_IMAGE_RESOLUTION_640x480;
else if(video_resolution.getSelectedIndex()==1) video_res=Kinect.NUI_IMAGE_RESOLUTION_1280x960;
myKinect.start(track_skeleton.isSelected(),depth_res,video_res);
myKinect.computeUV(true);
if(seated_skeleton.isSelected())myKinect.startSkeletonTracking(true);
if(near_mode.isSelected()) myKinect.setNearMode(true);
}
public static void main(String args[]) {
createMainFrame("Kinect Viewer App");
app=new KinectViewer();
setFrameSize(730,570,null);
System.out.print("main");
}
#Override
public void GUIactionPerformed(ActionEvent e)
{
if(e.getSource()==near_mode)
{
if(near_mode.isSelected()) myKinect.setNearMode(true);
else myKinect.setNearMode(false);
}
else if(e.getSource()==seated_skeleton)
{
if(seated_skeleton.isSelected()) myKinect.startSkeletonTracking(true);
else myKinect.startSkeletonTracking(false);
}
else if(e.getSource()==track_skeleton)
{
if(track_skeleton.isSelected())
{
if(seated_skeleton.isSelected()) myKinect.startSkeletonTracking(true);
else myKinect.startSkeletonTracking(false);
}
else myKinect.stopSkeletonTracking();
}
else if(e.getSource()==turn_off)
{
if(turn_off.getText().compareTo("Turn off")==0)
{
myKinect.stop();
turn_off.setText("Turn on");
}
else
{
turn_off.setText("Turn off");
resetKinect();
}
}
else if(e.getSource()==depth_resolution)
{
resetKinect();
}
else if(e.getSource()==video_resolution)
{
resetKinect();
}
else if(e.getSource()==show_video)
{
main_panel.setShowVideo(show_video.isSelected());
}
else if(e.getSource()==mask_players)
{
myKinect.maskPlayers(mask_players.isSelected());
}
}
#Override
public void stateChanged(ChangeEvent e) {
if(e.getSource()==elevation_angle)
{
if(!elevation_angle.getValueIsAdjusting())
{
myKinect.setElevationAngle(elevation_angle.getValue());
elevation_angle.setToolTipText("Elevation Angle ("+elevation_angle.getValue()+" degrees)");
}
}
}
}
However, when I run this, I get this following NPE:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at edu.ufl.digitalworlds.gui.DWApp.<init>(DWApp.java:173)
at skeleton.KinectViewer.<init>(KinectViewer.java:53)
at skeleton.TestSplitPanels$1.actionPerformed(TestSplitPanels.java:66)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Why is this?
Please note that KinectViewer can be opened as its own java application and works just fine by itself and if you are wondering about the DWApp, the DWApp class is a class in the edu.ufl.digitalworlds.gui package in the ufdw.jar (downloaded via this site posted above). It has two types of its class: one for a java application (which I'm using) and one for an applet. Inside the class are a bunch of methods seeming to deal with application look and processes (word sizing, formating, error dialogs, ect.). During setting everything up, I imported a project from git, and used a uri of "research.dwi.ufl.edu/j4kdemo".
I'm getting a NullPointerException in my JList, but the source of the exception seems to be the Swing event handling code. The JList has a key listener which will delete the selected item when the Delete key is pressed. The exception is only thrown on the second and all subsequent deletions from the list. Any ideas on how to fix it?
Sample code to reproduce the problem and the exception that is produced are included below:
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JList;
public class Sample {
public static void main(String[] args) {
final JFrame frame = new JFrame();
final Vector<String> list = new Vector<String>();
for (int i = 0; i < 5; ++i) {
list.add("String " + i);
}
final JList listView = new JList(list);
listView.addKeyListener(new KeyListener() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DELETE) {
list.remove(listView.getSelectedIndex());
listView.updateUI();
}
}
#Override
public void keyReleased(KeyEvent e) { }
#Override
public void keyTyped(KeyEvent e) { }
});
frame.add(listView);
frame.pack();
frame.setVisible(true);
}
}
Here's the exception being thrown:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.plaf.basic.BasicListUI$Handler.isNavigationKey(Unknown Source)
at javax.swing.plaf.basic.BasicListUI$Handler.keyPressed(Unknown Source)
at java.awt.AWTEventMulticaster.keyPressed(Unknown Source)
at java.awt.Component.processKeyEvent(Unknown Source)
at javax.swing.JComponent.processKeyEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
The problem is in this line:
listView.updateUI();
Calling this method causes the current UI to be uninstalled from the JList, yet it is still being used to process events. This results in the NullPointerException you see. This isn't the method you want to call.
Try
listView.revalidate();
instead to cause the component to re-layout or perhaps just repaint() to get it to repaint.
list.registerKeyboardAction(this,
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), JComponent.WHEN_FOCUSED);
EDIT: remove unrelated code
Instead of the updateUI() you should call the revalidate() and repaint() method. And probably a check if the element in the list really exists wouldn't be a bad idea.
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_A) {
if(list.get(listView.getSelectedIndex()) != null) {
list.remove(listView.getSelectedIndex());
listView.revalidate();
listView.repaint();
}
}
}
I basically want to serialize an ArrayList in Java, and here is the code that apparently needs to be changed. (EDIT: pasted entire class)
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.ArrayList;
import javax.swing.*;
public class GraphEditSerial extends JFrame{
//stores all dots on the MainPanel
private ArrayList<Circle> circles = new ArrayList<Circle>();
class Circle implements Serializable{
private static final long serialVersionUID = -8364830119753788192L;
private int x, y;
public String toString(){
return "("+x+", "+y+")";
}
public Circle(int x, int y) {
this.x = x;
this.y = y;
}
}
//variables for current workmode
private boolean canInsert = false;
private boolean canDelete = false;
private boolean canMove = false;
private boolean wasMoved = false;
//defines a JPanel and adds a MouseListener
class MainPanel extends JPanel implements MouseListener{
//constructor
public MainPanel(){
setBackground(Color.white);
addMouseListener(this);
}
//paints a blue spot on specified location
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.blue);
for (Circle k: circles) {
g.fillOval(k.x - 5, k.y - 5, 10, 10);
}
}
public void mouseClicked(MouseEvent e) {
//user wants to add a circle
if(canInsert){
//adds new circle to ArrayList and displays all circles
circles.add(new Circle(e.getX(), e.getY()));
repaint();
}
//user wants to delete a circle
else if(canDelete){
//checking if clicked position is within 4px of existing circles
for (int k=0; k<circles.size();k++){
Circle c = circles.get(k);
if(c.x-e.getX()<=4
&&c.x-e.getX()>=-4
&&c.y-e.getY()<=4
&&c.y-e.getY()>=-4){
//removes circle that is within 4 px of clicked position
circles.remove(k);
}
}
repaint();
}
}
//used to move existing circles, but only if current workmode = move
public void mousePressed(MouseEvent e) {
//current workmode has to be "move"
if(canMove==true){
//checking if clicked position is within 4px of existing circles
for (int k=0; k<circles.size();k++){
Circle c = circles.get(k);
if(c.x-e.getX()<=4
&&c.x-e.getX()>=-4
&&c.y-e.getY()<=4
&&c.y-e.getY()>=-4){
//removes circle that is within 4 px of clicked position
circles.remove(k);
wasMoved=true;
}
}
}
}
//displays moved circle at current position of mouse
public void mouseReleased(MouseEvent e) {
//current workmode has to be "move"
if(canMove==true){
//checking if user clicked on an existing circle before
if(wasMoved==true){
circles.add(new Circle(e.getX(), e.getY()));
repaint();
wasMoved=false;
}
}
}
//not assigned
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
//Menu
JMenuBar mb = new JMenuBar();
JMenu graph = new JMenu("Graph");
JMenu vertex = new JMenu("Vertex");
JMenuItem open = new JMenuItem("open");
JMenuItem mnew = new JMenuItem("new");
JMenuItem save = new JMenuItem("save");
JMenuItem insert = new JMenuItem("insert");
JMenuItem move = new JMenuItem("move");
JMenuItem delete = new JMenuItem("delete");
JMenuItem none = new JMenuItem("none");
//FileChooser
JFileChooser fc;
//main panel
MainPanel main = new MainPanel();
//bottom row
JPanel bottomrow = new JPanel(new GridLayout(1,2));
JLabel l1 = new JLabel("Selected Action: ", SwingConstants.RIGHT);
JTextField l2 = new JTextField("none", SwingConstants.LEFT);
//setting up a Menu with MenuItems, Dimensions, ActionListeners, etc...
public GraphEditSerial(String s){
super(s);
//adding menu items to menus
graph.add(open);
graph.add(mnew);
graph.add(save);
vertex.add(insert);
vertex.add(move);
vertex.add(delete);
vertex.add(none);
fc = new JFileChooser();
//Label l2 changes accordingly to selected MenuItem
open.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("Graph: open");
canInsert=false; canDelete=false; canMove=false;
repaint();
int returnVal = fc.showOpenDialog(GraphEditSerial.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File f = fc.getSelectedFile();
try{
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList<Circle> a = (ArrayList<Circle>)ois.readObject();
circles = a;
repaint();
}
catch (ClassNotFoundException e) {}
catch (IOException e){}
}
}
});
mnew.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("Graph: new");
canInsert=false; canDelete=false; canMove=false;
//clears all vertexes
circles.clear();
repaint();
}
});
save.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("Graph: save");
canInsert=false; canDelete=false; canMove=false;
repaint();
int returnVal = fc.showSaveDialog(GraphEditSerial.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
String datname = fc.getSelectedFile().getAbsolutePath().toString();
try{
FileOutputStream fos = new FileOutputStream(datname);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject((ArrayList<Circle>) circles);
oos.close();
}
catch (IOException e){
l2.setText(e.toString());
e.printStackTrace();
}
}
}
});
insert.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("Vertex: insert");
canInsert=true; canDelete=false; canMove=false;
repaint();
}
});
move.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("Vertex: move");
canInsert=false; canDelete=false; canMove=true;
repaint();
}
});
delete.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("Vertex: delete");
canInsert=false; canDelete=true; canMove=false;
repaint();
}
});
none.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("none");
canInsert=false; canDelete=false; canMove=false;
repaint();
}
});
bottomrow.add(l1);
bottomrow.add(l2);
main.setPreferredSize(new Dimension(500,300));
main.setOpaque(true);
main.setBackground(Color.WHITE);
mb.setPreferredSize(new Dimension(500, 20));
mb.add(graph);
mb.add(vertex);
setJMenuBar(mb);
add(main, BorderLayout.CENTER);
add(bottomrow, BorderLayout.PAGE_END);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
pack();
setVisible(true);
setLocationRelativeTo(null);
}
public static void main(String[] arg){
//new GraphEditor("MyGraphEditor");
new GraphEditSerial("MyGraphEditor");
}
}
I did it without the JFileChooser and just specified a filename, and it worked like a charm. I could also deserialize it without problems. But as soon as I use JFileChooser, I get "java.io.NotSerializableException: javax.swing.plaf.metal.MetalFileChooserUI"
Anyone got an idea?
EDIT: this is what e.printStackTrace() prints
java.io.NotSerializableException: javax.swing.plaf.metal.MetalFileChooserUI
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at javax.swing.event.EventListenerList.writeObject(Unknown Source)
at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteObject(Unknown Source)
at javax.swing.JComponent.writeObject(Unknown Source)
at sun.reflect.GeneratedMethodAccessor10.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteObject(Unknown Source)
at java.awt.Window.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at java.awt.Window.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at java.util.ArrayList.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at GraphEditSerial$3.actionPerformed(GraphEditSerial.java:202)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Is Circle an inner class of your UI class itself? If it is an inner class and fc is a field of the outer class the writeObject on a Circle element will try to serialize not only its fields but its outer-class's fields too. And if fc is a field of the outer-class and a MetalFileChooserUI then it will obviously fail serialization.
That's the best guess I can come up with from your code snippet. If that doesn't answer your question, as vanza says we would need more information on the content of the Circle
It looks like you are saving some object which has this (anonymous) ActionListener attached, or somehow references an object which in turn references this ActionListener. The ActionListener, in turn references the fc object, which is a JFileChooser. The JFileChooser itself knows its UI object (which does all the work such that the file chooser fits in your system), and this one is not serializable.
There is no point in serializing a JFileChooser. The only interesting data it would contain are the file or directory name, which anyway could be unusable on another system.
An easy solution would be moving the fc inside the actionPerformed method, and initialize it there (creating a new JFileChooser).
But you really want to have a look why your ActionListener (or the object it is attached to) is serialized - this sometimes could be useful, but most probably you don't want your GUI to be serialized at all, only the data. To have some insight, change
catch (IOException e){l2.setText(e.toString());}
to
catch (IOException e){
l2.setText(e.toString());
e.printStackTrace();
}
and look at the stack trace from standard output. It should show you a hint which objects are tried to serialize. It could be that your Circles have a reference to some object which they shouldn't, really. (Or a reference which should be transient. Or that they are objects of an inner class when they should not.)
I just wanted to add some additional information about that problem because I ran over exactly this error (probably because I am a student at the same university with the same lecturer and the exact same task :D).
In this blogpost I analysed this adverse constellation in detail: try to serialize an inner class with an outer class that handles events and uses jfilechooser, which fails:
http://hannes-schurig.de/21/11/2012/java-problem-beim-serialisieren-von-objekten-bei-der-verwendung-von-ereignishandlern-jfilechooser/
It's in german but I think it's easy to get the point, important things are highlighted.