Null pointer exception while trying to modify a JFrame from another class? - java

EDITED CODE:
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new StartPanel());
frame.add(new InstructionsPanel());
frame.add(new GamePanel());
frame.getContentPane().getComponent(1).setVisible(false);
frame.getContentPane().getComponent(2).setVisible(false);
frame.setPreferredSize(new Dimension(500, 500));
frame.pack();
frame.setVisible(true);
}
No matter what outside class I try to modify the frame from (any of the 3 panel classes above), I get a null pointer exception pointing to the line I am modifying something in the frame.

Your Panel classes are created before the JFrame is created so the JFrame will be null in the Panel class constructors. But as per my comment, you should bring your code into the instance world by getting rid of those static modifiers. Your whole program design, to put it mildly, smells. Your main method should instead look something like:
private static void createAndShowGui() {
// Model model = new MyModel();
View view = new View();
// Control control = new MyControl(model, view);
JFrame frame = new JFrame("My GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(view.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
And View could look like:
public class View
private StartPanel s = new StartPanel();
private InstructionsPanel i = new InstructionsPanel();
private GamePanel g = new GamePanel();
private JPanel mainComponent = new JPanel();
public View() {
// create your GUI here
// add components to mainComponent...
}
public JComponent getMainComponent() {
return mainComponent;
}
}

Related

passing frame as parameter in method

i want to pass a JFrame as parameter in a method,
is it possible to do that ?
here is what i want :
private void mouseClickedButtonsActions(JLabel l, Class c){
l.addMouseListener(new java.awt.event.MouseAdapter() {
#Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
c ma = new c();
ma.setVisible(true);
setVisible(false);
}
});
}
You shouldn't be sending Class in this situation, if you want to learn more about sending class as parameter check this out Passing class as parameter.
Now since you want to pass JFrame as parameter you can simply write methodName(JFrame frame), otherwise if you just want to make new JFrame you don't need to pass it but just create new one inside method:
myMethod(){
JFrame frame = new JFrame();
// Do something with it
}
So as you can see there is no need to pass an Class in other to make object of that class.
Here you can see example of how to pass JFrame as parameter and make new JFrame:
public void jframe() {
JFrame frame = new JFrame("Frame 1");
JButton btn = new JButton("Click Me");
ActionListener al = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
jframeAsParam(new JLabel("You added label to old JFrame"), frame);
//makeNewJFrame(new JLabel("You opened new JFrame"));
}
};
btn.addActionListener(al);
JPanel panel = new JPanel(new GridLayout(2, 1));
panel.add(btn);
frame.setContentPane(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 250);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void jframeAsParam(JLabel lbl, JFrame frame) {
frame.getContentPane().add(lbl);
frame.setVisible(true);
}
public void makeNewJFrame(JLabel lbl) {
JFrame frame = new JFrame("Frame 2");
JPanel panel = new JPanel(new BorderLayout());
panel.add(lbl, BorderLayout.CENTER);
frame.setContentPane(panel);
frame.setSize(300, 250);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
Uncomment makeNewJFrame(new JLabel("You opened new JFrame")); to see how opening new JFrame works.
c ma = new c();
First of all class names should:
Start with an upper case character
Be descriptive
i want to pass a JFrame as parameter in a method, is it possible to do that ?
There is no need to pass the frame as a parameter you can access the current frame by using code like:
Component component = (Component)evt.getSource();
Window window = SwingUtilities.windowForComponent( component );
window.setVisible( false );

JScrollPane in JFrame

I want to write a simple Java program, which consists of a JFrame that integrates a JScrollPane. Just it does not work the way I do it.
What is the issue of the my approach ?
public class TestView {
JFrame frame;
JScrollPane scrollPane;
public TestView(){
frame = new JFrame();
scrollPane = new JScrollPane();
scrollPane.add(new JLabel("Klick me"));
scrollPane.setMinimumSize(new Dimension(200,200));
frame = new JFrame();
frame.getContentPane().add(scrollPane);
frame.setSize(200,200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void createAndShowGui(){
TestView tv = new TestView();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGui();
}
});
If the issue is that you do not see your label in the scrollpane, you might need to use
scrollpane.setViewportView(new JLabel("Klick me"));
instead of
scrollPane.add(new JLabel("Klick me"));
Additionally, I suggest you create a JPanel, give it a layout, and place your label there, instead of passing the label to the scrollpane. Then set this panel as the viewport.
Please see
Difference between JscrollPane.setviewportview vs JscrollPane.add
use for example:
final JPanel myPanel = new JPanel();
myPanel.setPreferredSize(new Dimension(50, 50));
final JScrollPane scrollPane = new JScrollPane(myPanel);
setMinimumSize will be ignored.

JScrollPane does not work on JPanel

I have a frame that contains a mainPanel. This last will add other commandPanels (each one contains a button and a textField) Dynamically. the problem is that the JScrollPane does not appear to let me use the unseen commandPanels even if the mainPanel is full.
The below picture shows my case.
To initialize the window I wrote below code:
frame = new JFrame();
frame.setBounds(100, 100, 962, 639);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
mainPanel = new JPanel();
mainPanel.setBounds(264, 6, 692, 500);
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
scroll = new JScrollPane();
scroll.getViewport().add(mainPanel);
frame.getContentPane().add(scroll);
and the method that add dynamically the new commandPanels is:
public void loadCommandPanel(String commandName)
{
CommandPanel newCommandPanel = new CommandPanel();
newCommandPanel.getCommandBtn().setText(commandName);
mainPanel.add(newCommandPanel);
scroll.getViewport().add( newCommandPanel );
mainPanel.add( scroll, BorderLayout.EAST);
frame.add( mainPanel);
...
}
Any help to get the scrollPane, will be much more than appreciated.
scroll.getViewport().add(mainPanel); is not how you use JViewport or JScrollPane; instead you should using something like this:
scroll.getViewport().setView(newCommandPanel);
or
scroll.setViewportView(newCommandPanel);
Take a look at How to Use Scroll Panes for more details.
Note also, this doesn't makes sense:
CommandPanel newCommandPanel = new CommandPanel();
newCommandPanel.getCommandBtn().setText(commandName);
mainPanel.add(newCommandPanel);
scroll.getViewport().add( newCommandPanel );
You add newCommandPanel to mainPanel, then promptly add it to another container (albeit incorrectly).
A component can only reside on a single parent; the moment you add it to another container, it is automatically removed from the previous container.
I have made some changes and it works perfectly now. For those who want the same thing here's my code:
import ...
public class mainUserInterface {
private JFrame frame;
private JPanel mainPanel;
private JPanel commandsPanel;
private JScrollPane commandsScrollPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
mainUserInterface window = new mainUserInterface();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public mainUserInterface() {
initialize();
}
private void initialize() {
frame = new JFrame("CommandsExecutor");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(1000, 700));
mainPanel = new JPanel(new BorderLayout(5,5));
mainPanel.setBorder( new TitledBorder("") );
commandsPanel = new JPanel();
commandsPanel.setLayout(new BoxLayout(commandsPanel, BoxLayout.Y_AXIS));
for(int i=0; i<15;i++){
commandsPanel.add(new CommandPanel());
}
commandsScrollPane = new JScrollPane(commandsPanel);
mainPanel.add(commandsScrollPane,BorderLayout.CENTER);
frame.setContentPane(mainPanel);
frame.pack();
frame.setVisible(true);
}
}
and Here's the commandPanel class:
import ...
public class CommandPanel extends JPanel {
private JTextField commandResult;
private JButton commandBtn;
public CommandPanel()
{
this.setLayout( new BorderLayout(10,10));
this.setBorder( new TitledBorder("Command:") );
this.setMaximumSize(new Dimension(692,60));
this.setMinimumSize(new Dimension(692,60));
commandBtn = new JButton("Execute");
commandBtn.setMaximumSize(new Dimension(137, 34));
commandBtn.setMinimumSize(new Dimension(137, 34));
this.add(commandBtn, BorderLayout.WEST);
commandResult = new JTextField();
commandResult.setMaximumSize(new Dimension(518, 34));
commandResult.setMinimumSize(new Dimension(518, 34));
this.add(commandResult, BorderLayout.CENTER);
}
public JTextField getCommandResult() {
return commandResult;
}
public JButton getCommandBtn() {
return commandBtn;
}
public void setCommandResult(JTextField commandResult) {
this.commandResult = commandResult;
}
public void setCommandBtn(JButton commandBtn) {
this.commandBtn = commandBtn;
}
}
Thanks for all who answered my question, it really helped.

JFrame not displaying contents

I know this question has been asked a lot, but ive read through about 10 different articles, all reccomending to different things such as "frame = this" nad frame.add(d)" Im not sure why, but none of these have been working. I typed something and the program worked fine, except the Jbuttons wouldnt show up until i clicked on the JFrame a few times. After some tweaking of that code, im back to the start. Now i just get a error:
Exception in thread "main" java.lang.NullPointerException
at Guis.Dynamic_JFrame.<init>(Dynamic_JFrame.java:37)
at Guis.Dynamic_JFrame.main(Dynamic_JFrame.java:46)
Heres my code:
public class Dynamic_JFrame extends JFrame{
static JFrame frame;
Graphics g;
Handler handler = new Handler();
JButton red = new JButton();
JButton green = new JButton();
JButton orange = new JButton();
public Dynamic_JFrame(){
red.setText("RED");
green.setText("GREEN");
orange.setText("orange");
add(green);
add(red);
add(orange);
red.addActionListener(handler);
green.addActionListener(handler);
orange.addActionListener(handler);
frame.setVisible(true);
}
public static void main(String[] args){
Dynamic_JFrame d = new Dynamic_JFrame();
frame = new JFrame("Changing colors");
frame.setPreferredSize(new Dimension(500,500));
frame.setMaximumSize(new Dimension(500,500));
frame.setMinimumSize(new Dimension(500,500));
frame.setLayout(new FlowLayout());
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public class Handler implements ActionListener{
public void actionPerformed(ActionEvent e) {
if(e.getSource()==red){
getContentPane().setBackground(Color.RED);
}
if(e.getSource()==green){
getContentPane().setBackground(Color.GREEN);
}
if(e.getSource()==orange){
getContentPane().setBackground(Color.ORANGE);
}
}
}
}
New code, Minor Changes. Program works as intended except for the buttons not updating until i click where they should be:
JFrame frame;
public Dynamic_JFrame(){
frame = new JFrame();
frame = this;
red.setText("RED");
green.setText("GREEN");
frame.add(green);
frame.add(red);
frame.setVisible(true);
}
public static void main(String[] args){
Dynamic_JFrame d = new Dynamic_JFrame();
d.frame.setPreferredSize(new Dimension(500,500));
d.frame.setMaximumSize(new Dimension(500,500));
d.frame.setMinimumSize(new Dimension(500,500));
d.frame.setLocationRelativeTo(null);
d.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
d.frame.setLayout(new FlowLayout());
}
A number of things...
Firstly, Dynamic_JFrame extends from JFrame so I don't know why you've then gone and create another frame...
Secondly, when Dynamic_JFrame calls frame.setVisible in the constructor, frame is null as it has not being initialised.
From my perspective, the simplest solution would be to extend Dynamic_JFrame from something like JPanel instead and simply add it to an instance of JFrame
For example...
public class Dynamic_JFrame extends JPanel {
static JFrame frame;
// Not sure that this is a good idea...
Graphics g;
//...
public Dynamic_JFrame(){
// Don't use this...
//frame.setVisible(true);
}
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
public void run() {
Dynamic_JFrame d = new Dynamic_JFrame();
frame = new JFrame("Changing colors");
frame.setLayout(new FlowLayout());
frame.add(d);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}

Why not jframe shows button?

public class Benim extends JFrame {
Container contentArea = getContentPane ();
public Benim(){
JFrame frame=new JFrame("Concentration");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
setSize(800, 800);
JButton start=new JButton("Start");
JPanel pane=new JPanel();
pane.add(start);
setVisible(true);
frame.add(start);
frame.add(pane);
/* setContentPane(Container)
JRootPane createRootPane()*/
}
public static void main (String []args){
new Benim();
}
}
My code is that. I tried adding to panel first then adding panel to frame, adding to frame directly. Adding a rootpane but still my button doesnot appear. I am trying to learn for 2 days but i am still at same point.
The instance of JFrame that is shown does not have the JButton added.
Instead invoke setVisible on the JFrame directly
You almost never want to extend JFrame as no new functionality is added
Other points to note
Call setVisible after components have been added
setSize is unnecessary - let pack determine container size
This is the result
public class Benim extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Concentration");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton start = new JButton("Start");
JPanel pane = new JPanel();
pane.add(start);
pane.add(start);
frame.add(pane);
frame.pack();
frame.setVisible(true);
}
});
}
}
Why another instance of JFrame? You are extending it, so just call super().
public class Benim extends JFrame {
Container contentArea = getContentPane ();
public Benim(){
super("Concentration");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setSize(800, 800);
JButton start=new JButton("Start");
JPanel pane=new JPanel();
pane.add(start);
add(pane);
setVisible(true);
}
public static void main (String []args){
new Benim();
}
}
Reimeus also rightfully points out that you don't need to extend JFrame if you don't plan on extending functionality. See his example for an alternative implementation.

Categories

Resources