0

despite some tips, I'm still getting this one wrong. I end up with one basic window and another one with extra features, but without the basic ones from the previous window. Instead, I would like one new window combining the basic and new features. Here is the code I've got: (also which approach would you advise?)

package windows;

import java.awt.*;
import javax.swing.*;

public abstract class WindowTemplate extends JFrame {

/**
 * Create the GUI and show it. For thread safety, this method should be
 * invoked from the event-dispatching thread.
 */
public WindowTemplate () {

JFrame myFrame = new JFrame("My first window");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setVisible(true);
myFrame.setSize(550, 450);
myFrame.setLocationRelativeTo(null);

// JLabel emptyLabel = new JLabel("");
// emptyLabel.setPreferredSize(new Dimension(550, 450));

// myFrame.getContentPane().setLayout(new CardLayout());
// myFrame.getContentPane().add(emptyLabel, BorderLayout.CENTER);

// myFrame.pack();

}

}

now the one that is meant to be "extended":

package windows;

import java.awt.*;
import javax.swing.*;

public class a_Welcome extends WindowTemplate {

public a_Welcome() {

JPanel area = new JPanel();

JLabel text = new JLabel("One line another line and another line"); // , JLabel.CENTER);

// text.setBounds(80, 400, 400, 50);
add(area);

// area.setLayout(null);
area.add(text, new CardLayout());

// area.add(text); // , BorderLayout.CENTER);

Font font = new Font("SansSerif", Font.BOLD, 30);
text.setFont(font);
text.setForeground(Color.green);
area.setBackground(Color.darkGray);
area.setSize(550, 450);

}

}

// timer-after 5 seconds-go to the next window (countdown in the bottom right corner)

and the main:

package windows;

public class Launcher {

public static void main(String[] args) {

// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
    public void run() {

        // WindowTemplate.createWindow();
        // a_Welcome.createWindow();

         a_Welcome window = new a_Welcome();
         window.setVisible(true);
    }
});

}

}



-- Alternatively --

public class WindowTemplate extends JFrame {

// Constructor
public WindowTemplate() {
    init();
}

public void init() {
    // add basic components
    JFrame myFrame = new JFrame("My first window");
    myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    myFrame.setVisible(true);
    myFrame.setSize(550, 450);
    myFrame.setLocationRelativeTo(null);
}
}

and

public class a_Welcome extends WindowTemplate {

public a_Welcome() {
    super();
}

@Override
public void init() {
    super.init(); // important so you get the base stuff
    // add other components
    JPanel area = new JPanel();
    JLabel text = new JLabel("One line another line and another line");
    add(area);
    area.add(text, new CardLayout());

    Font font = new Font("SansSerif", Font.BOLD, 30);
    text.setFont(font);
    text.setForeground(Color.green);
    area.setBackground(Color.darkGray);
    area.setSize(550, 450);

}
}

Sorry for lots of code and thanks for your help!

4
  • 2
    a_Welcome is not idiomatic Java and a terrible class name regardless of language. Commented Jul 20, 2011 at 20:35
  • Yes, I know that. But it makes life easier for me, as it is the first window and the "a_" bit makes sure it stays on the top. Be sure it was not a way to write "a window". Obviously, I will change it properly. Commented Jul 20, 2011 at 20:40
  • @Jarrod Roberson: in the package explorer window in Eclipse. Commented Jul 20, 2011 at 20:56
  • @Jonas: Yes, a quick refactor and it will be named Welcome. Don't worry guys;) Commented Jul 20, 2011 at 20:57

4 Answers 4

3

I'm not quite sure what your problem is, but your WindowTemplate basically is a JFrame, so you don't want to create a new JFrame in your constructor but rather "apply" those method to this instead of myFrame. Try something like this:

public WindowTemplate()
{
    super("My first window");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // "this" is optional
    setVisible(true);
    setSize(550, 450);
    setLocationRelativeTo(null);
}

and

public a_Welcome()
{
    super(); // this is implicit, because a_Welcome extends WindowTemplate, which has got a constructor without parameters
    //[add more stuff here]

}

When you're creating a new a_Welcome, its constructor will call the super constructor, which is WindowTemplate which will in turn call the JFrame constructor

Sign up to request clarification or add additional context in comments.

Comments

2

First, although you extend JFrame, you create a new JFrame and use it in each constructor. It should be looking like that:

public WindowTemplate () {

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.setPreferredSize(new Dimension(550, 450));
    this.pack();
    this.setVisible(true);

Now, if you do it like that, you can add JComponents in each constructor / init method. Instead, you create two separate JFrames, one in each constructor.

I would recommend to avoid too deep hierarchy in case of swing components, since you will face many unexpected layout issues, what works for one, doesn't work for the other, when more components are added.

7 Comments

Regarding your recommendation - I will have a few similar types of windows and I am planning to use CardLayout. The components would be text fields and areas, buttons, radiobuttons and so on (quite basic stuff). What design would recommend in this case?
For card layouts, you can extend JPanel, not JFrame, and except of really basic configuration, I would not create an hierarchy, unless it is really a big issue to create the full panel each time. If possible, I would add some common components to the main JFrame, and have all panels inside some other panel, but it really depends on your needs.
I could be creating the whole window from scratch for every single window, because it is just a few lines, but I heard it is not good to repeat your code. I don't quite get the idea of having "all panels inside some other panel".
It really isn't the best ting to do, but I think that separation is needed in some places, but that's, again, depends on your needs. The idea of "all panels inside another panel", is that panel is a container, and you can populate it with more panels. A frame is a whole new window (more or less)
Ok, thanks. I would be grateful if you could have a look at link where I asked about the design. I think it is very important to plan it properly before it is too late to do any changes.
|
1

I think in your second example, in WindowTemplate, you're creating another JFrame when you think you're initializing the this JFrame.

Instead of

JFrame myFrame = new JFrame("My first window");

you probably want

super("My first window");

and then replace any myFrame references thereafter with this

Comments

0

If I read your code correctly, WindowTemplate is a JFrame. And within WindowTemplate's constructor you instantiate another JFrame? This does not make much sense. Instead of creating and configuring myFrame, you should configure this

public WindowTemplate () {

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    ...
}

as you are doing it in the subclass, where you are calling this.add(area)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.