0

EDIT2: Ok, I hope this is how you do it. Below is the thinned version of the classes I used. The error still persists if I have all the Getters and Setters inside the SurfaceObject() classe, but seems to disappear if I exclude them. Which is quite weird. Even weird is that it also seems to appear if the variables are all private, and not, as in the example, protected. So I would like to know why that's the case: Main Class (Builds JFrame):

import javax.swing.JFrame;
public class FileCreator extends JFrame{
    private static FileCreator chooseAction;
    private Container contain;
    public static final int framewidth = 800;
    public static final int frameheight = 600;
    private final String[] iconName = {"Load File"};
    public static void main(String[] args) {
        chooseAction = new FileCreator();
    }
    public FileCreator(){
        super("Editor");
        contain = new Container(iconName, this);
        add(contain);
        setSize(framewidth,frameheight);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);

    }
}

This class builds the container and adds the cards to it (First Card is holdContent, second Card is the FirstOptionPanel). It also adds the ActionListener MainListener, which in turn calls the createPanel()-Method

import java.awt.CardLayout;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JPanel;
class Container extends JPanel {
    private FirstOptionPanel[] panels = new FirstOptionPanel[9];
    private final String[] cardNames = { "card1", "File Loaded" };
    private JButton[] buttons;
    private MainMenuListener main;
    private int contentWidth = 410, contentHeight = 300;
    private CardLayout cards;
    Container(String[] buttonName,
            FileCreator creator) {
        super();
        setLayout(cards = new CardLayout());
        setSize(FileCreator.framewidth, FileCreator.frameheight);
        buttons = new JButton[buttonName.length];
        int i = 0;
        buttons[i] = new JButton(buttonName[i]);
        main = new MainMenuListener(this, creator);
            buttons[i].addActionListener(main);
        JPanel card1 = new JPanel();
        card1.setSize(getWidth(), getHeight());
        card1.setLayout(null);
        JPanel holdContent = new JPanel();
        holdContent.setSize(contentWidth, contentHeight);
        holdContent.setLocation((FileCreator.framewidth - contentWidth) / 2,
                (FileCreator.frameheight - contentHeight) / 2);
        holdContent.add(buttons[i]);
        card1.add(holdContent);
        add(card1, cardNames[0]);
    }
    public JButton[] getButtons() {
        return buttons;
    }
    public void createPanel(int i, File selectedFile) {
        panels[i] = new FirstOptionPanel(selectedFile);
        add(panels[i], cardNames[i + 1]);
        cards.show(this, cardNames[i + 1]);
    }
}

This class is the ActionListener. It just registers the pressed button and calls the createPanel()-method upon pressing load File. However, the JFileChooser does nothing in this version. Normally, it loads the file and passes it.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class MainMenuListener implements ActionListener {
    private JButton[] buttons;
    private JPanel[] panellist;
    private Container container;
    private JFileChooser jf;
    private FileCreator creator;
    public MainMenuListener(Container container, FileCreator creator) {
        // TODO Auto-generated constructor stub
        buttons= container.getButtons();
        this.creator = creator;
        panellist = container.getPanels();
        this.container = container;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        for(int i = 0; i<buttons.length;i++){if(i == 0){
                jf = new JFileChooser();
                int returnValue = jf.showOpenDialog(container);     
                if(returnValue == JFileChooser.APPROVE_OPTION){
                    container.createPanel(i, jf.getSelectedFile());
                }else       if(returnValue == JFileChooser.CANCEL_OPTION){
                    JOptionPane.showMessageDialog(creator, "No File selected!");
                }

            }
        }
    }
    }

This here is the FirstOptionPanel class. It's a JPanel that creates other JPanels (in this case a single entry-Object), and then displays them:

import java.io.File;
import javax.swing.JPanel;

public class FirstOptionPanel extends JPanel{
    private SurfaceObject[] entries;
    JPanel buttonHolder;
    public FirstOptionPanel(File selectedFile) {
        // TODO Auto-generated constructor stub
        super();
        setSize(FileCreator.framewidth, FileCreator.frameheight);
        setLayout(null);
        createObjects();
            }
    public FirstOptionPanel() {
        // TODO Auto-generated constructor stub
        super();
    }
    private void createObjects() {
                entries = new SurfaceObject[1];
                    entries[0] = new SurfaceObject("ENTRIES{|,Logo1,,1,,100,,100,,100,,100,|}");
                    add(entries[0]);
                }

}

And finally, the SurfaceObject class. The aforementioned SurfaceEntry-Class extends this class. SurfaceEntry() is not used here, but the error still occurs. But only if I have all these different getters() and setters(). If I don't include them, the programm runs just fine. Even though I don't actually use them yet!(Large File ahead):

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MouseInfo;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class SurfaceObject extends JPanel{
    /**
     * 
     */
    private String iconName;
    private int id;
    int coordinates[] = new int[2];
    int momentaryCoord[] = new int[2];
    protected boolean imageNotFound;
    protected int[] sizeOfRectangle = new int[2];
    protected String pictureName;
    protected ImageIcon momentaryPicture;
    protected Image img;
    protected boolean mouseInAction;
    protected Dimension d;
    protected boolean selected;
    private FirstOptionPanel parent;
    public SurfaceObject(String group) {
        super();
    }

    @Override
    protected void paintComponent(Graphics g) {
        // TODO Auto-generated method stub
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        if (!imageNotFound) {
            g2.drawImage(img, 0, 0, null);
            System.out.println("shown");
        } else {
            System.out.println("Drawn");
            g2.setColor(Color.blue);
            g2.fillRect(0, 0, 200, 200);
        }

    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    public final String getIconName() {
        return iconName;
    }

    public final void setIconName(String iconName) {
        this.iconName = iconName;
    }

    public final int getId() {
        return id;
    }

    public final void setId(int id) {
        this.id = id;
    }

    public final int[] getCoordinates() {
        return coordinates;
    }

    public final void setCoordinates(int[] coordinates) {
        this.coordinates = coordinates;
    }

    public final int[] getMomentaryCoord() {
        return momentaryCoord;
    }

    public final void setMomentaryCoord(int[] momentaryCoord) {
        this.momentaryCoord = momentaryCoord;
    }

    public final boolean isImageNotFound() {
        return imageNotFound;
    }

    public final void setImageNotFound(boolean imageNotFound) {
        this.imageNotFound = imageNotFound;
    }

    public final int[] getSizeOfRectangle() {
        return sizeOfRectangle;
    }

    public final void setSizeOfRectangle(int[] sizeOfRectangle) {
        this.sizeOfRectangle = sizeOfRectangle;
    }

    public final String getPictureName() {
        return pictureName;
    }

    public final void setPictureName(String pictureName) {
        this.pictureName = pictureName;
    }

    public final ImageIcon getMomentaryPicture() {
        return momentaryPicture;
    }

    public final void setMomentaryPicture(ImageIcon momentaryPicture) {
        this.momentaryPicture = momentaryPicture;
    }

    public final Image getImg() {
        return img;
    }

    public final void setImg(Image img) {
        this.img = img;
    }

    public final Dimension getD() {
        return d;
    }

    public final void setD(Dimension d) {
        this.d = d;
    }

    public final boolean isMouseInAction() {
        return mouseInAction;
    }

    public final FirstOptionPanel getParent() {
        return parent;
    }

}

This is the error message I get when I run the programm:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException
at javax.swing.LayoutComparator.compare(Unknown Source)
at javax.swing.LayoutComparator.compare(Unknown Source)
at java.util.TimSort.countRunAndMakeAscending(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at javax.swing.SortingFocusTraversalPolicy.enumerateAndSortCycle(Unknown Source)
at javax.swing.SortingFocusTraversalPolicy.getFocusTraversalCycle(Unknown Source)
at javax.swing.SortingFocusTraversalPolicy.getFirstComponent(Unknown Source)
at javax.swing.LayoutFocusTraversalPolicy.getFirstComponent(Unknown Source)
at javax.swing.SortingFocusTraversalPolicy.getDefaultComponent(Unknown Source)
at java.awt.FocusTraversalPolicy.getInitialComponent(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$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.SequencedEvent.dispatch(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)

I hope this is enough of an explanation to work with. Thanks in advance,

Nicolai

Nicolai
  • 21
  • 5
  • A guess: Are you using CardLayout on a JFrame, and are then adding components to that same JFrame. If so, understand that you are actually adding the layout to the JFrame's contentPane and not the JFrame itself, and you would then want to not use `this` in your CardLayout's method but rather `getContentPane()`. – Hovercraft Full Of Eels Aug 25 '14 at 20:47
  • If this doesn't help, please create and post a [minimal compilable and runnable example program](http://stackoverflow.com/help/mcve). – Hovercraft Full Of Eels Aug 25 '14 at 20:47
  • Sadly, that's not the case. All the "cards" are added to the container, while the container is added to the JFrame. The JFrame is only there to display the content. And why should I not use "this"? – Nicolai Aug 25 '14 at 20:50
  • What does this represent? But never mind that. Instead you will want to create and post your [mcve](http://stackoverflow.com/help/mcve) I think. – Hovercraft Full Of Eels Aug 25 '14 at 20:52
  • this represents the container, in this case. I will, if I can recreate the error. – Nicolai Aug 25 '14 at 20:56
  • Shouldn't the `add(entries[j])` calls in your `for (int j = 0; j <...` loop have String constants added with the components? This add method is not appropriate for a CardLayout. – Hovercraft Full Of Eels Aug 25 '14 at 21:11
  • -1 and vote to close as this is way too broad and unlikely to help anyone in the future. You are kindly asked by HFOE to provide an MVCE but instead you just post more code. SO is not a place to ask for others to debug your code. – Guillaume Polet Aug 25 '14 at 21:51
  • Well, I'm sorry, but as I stated in the comment, I do not know how to post MVCE. Should I upload a jar. file? a rar-archive? The site he linked me doesn't state how to post such a program... but I would be thankful if you could tell me how to do that, instead of just downvoting me? – Nicolai Aug 25 '14 at 21:54
  • @Nicolai You could simply follow the link provided by HFOE: [MVCE](http://stackoverflow.com/help/mcve) and read what's in it. It guides you through the entire process of building MVCE. No sorcellery, no mistery, no black magic. Follow the steps and you will get there. – Guillaume Polet Aug 25 '14 at 21:55
  • And how should I post it instead of "posting more code?" – Nicolai Aug 25 '14 at 21:56
  • Remove your previous code and only post your MVCE with some text explaining what you are looking for. – Guillaume Polet Aug 25 '14 at 22:03
  • You've posted much code that is completely unrelated to your problem at hand, and asking volunteers to slog through it is perhaps asking a bit too much. What you need to do is a little more work: whittle down the code to the *bare minimum* required to compile, and either run and show your misbehavior, or not run and show your error/exception. The *bare minimum* part is the essential bit that will allow us to be able to review a reasonable amount of code without having to trip over tons of unrelated and code. – Hovercraft Full Of Eels Aug 25 '14 at 22:07
  • For instance what does Pattern Matcher, ImageIcons, paintComponent methods, Threads, JFileChoosers, Files, etc... have to do with your current question or problem? – Hovercraft Full Of Eels Aug 25 '14 at 22:10
  • If I remove them, the problem does not occur anymore, as it has most likely to do with an action not called from the MainThread. For example, if I remove the while JFileChooser Clause, the error does not occur anymore. Same thing with the Getter/Setter Part, which is also the reason why I kept the Pattern and Matcher classes there. Also, I'm not sure which part to leave out, because the error message does not point to any point in my program, which makes it kind of hard to debug. Which is the reason why I posted this in the first place – Nicolai Aug 25 '14 at 22:22
  • Then you may be here prematurely for first you must isolate the part of your code that is causing the problem. I suggest that you delete sections of code and try to find out the guilty portion. Please remember that we are all volunteers with lives, jobs, families, and we enjoy helping and going through reasonable amounts of code, but don't have ability to do more than this. – Hovercraft Full Of Eels Aug 25 '14 at 22:24
  • The problem is that this kind of error-message (Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException) only appears in one or two other threads on Stackoverflow, and generally on the web, and they all seem to have different solutions. For the ClassCastException in general, I do know when it normally occurs, however this has nothing to do with wrong casting in a casual sense. Instead, as I gathered from the other posts, there is simply a wrong call in the non EDT. And because this is an error, as beforementioned, which occurs inside the virtual machine, I can't pinpoint it – Nicolai Aug 25 '14 at 22:28
  • The error is coming from an entity called the `LayoutComparator` and occur when adding components to your GUI. Focus on your GUI layouts, how you're adding components to containers. – Hovercraft Full Of Eels Aug 25 '14 at 22:47
  • As I said, the program works when I exclude the FileChooser. It also works when I make all variables private (In the class SurfaceObject). ALternatively, I can also exclude the get/set-methods. I also thought it has something to do with the GUI, however, how can the implementation of a JFileChooser or get/set-Methods change the GUI? I would like to know the connection between those two fundamentally different things. – Nicolai Aug 25 '14 at 23:04

1 Answers1

1

Found the answer to my question. For anyone wondering, it seems as if Java has a problem with the method "public FirstOptionPanel getParent()" of my SurfaceObject()-class. I explain this to myself with the reasoning that it is a method from a superclass. Which somehow makes it impossible to be created in another thread? If anyone has a more probable answer, I'm inclined to listen to it. (Eclipse just generated that get-method like that, I wouldn't have done it like that myself. If I change the methods name, the program works just fine)

Nicolai
  • 21
  • 5
  • I'm still not so sure... If I have time, please allow me to look into this further. Intriguing to say the least. – Hovercraft Full Of Eels Aug 27 '14 at 12:21
  • 1
    Yes, you're right. You're overriding the super's `getParent()` and you're changing the return type which is not kosher. If I were you, I'd also change the name of the Container class so as not to have a name clash there. 1+ to your answer. – Hovercraft Full Of Eels Aug 27 '14 at 17:29
  • Ah, alright, thanks for that piece of information. Now i know exactly why it didn't work as I anticipated. And you're completely right, I should not name it Container... gotta change that bit as well. Thanks again for the help in getting to know and understand the policies of this site a little better, and of course providing an explanation for the problem :) – Nicolai Aug 27 '14 at 20:16
  • 1
    You're welcome. Your problem is one argument against inheritance and towards composition. When inheriting large complex classes, there's always a danger of inadvertent method overrides that can lead to pernicious hard to detect errors. I ran into this in the past by giving a JPanel-extending class `getX()` and `getY()` methods. As an aside, you will want to avoid use of null layouts. You can easily center a component inside of another by giving the container a GridBagLayout, and then adding the component to the container in a default way, without GridBagConstraints. – Hovercraft Full Of Eels Aug 27 '14 at 20:20
  • So, in a way it's like a RelativeLayout in Android? Sounds pretty useful... every other Layout-Type I've tried so far was too constraining for my taste (I'm looking at you, FlowLayout). I will definetly take a look at it once I've implemented the basic functions... right now, making the editor work has a higher priority. – Nicolai Aug 28 '14 at 21:50