Java getContentPane().setBackground() not working - java

Im trying to encapsulate the GUI calls to a single class. My window appears but the background remains the default color instead of red.
ChatProgram.java
package ChatPkg;
public class ChatProgram {
/**
* Launch the application.
*/
public static void main(String[] args) {
ChatWindow.initialize();
ChatWindow.RunWindow();
}
}
ChatWindow.java
package ChatPkg;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.ListSelectionModel;
public final class ChatWindow {
static JFrame frame;
/**
* Create the application.
*/
private ChatWindow() { }
public static void RunWindow() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Initialize the contents of the frame.
*/
public static void initialize() {
frame = new JFrame("Chat program");
frame.setBounds(100, 100, 450, 450);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JCheckBox chckbxCvbc = new JCheckBox("cvbc");
frame.getContentPane().add(chckbxCvbc);
// Set background color
frame.getContentPane().setBackground(Color.red);
}
}
Yes i am new to Java and none of the google results solved my problem.

You should NOT add GUI components directly to the content pane of the JFrame. Also, you shouldn't modify its properties (like you tried changing the background).
You always need a JPanel that acts as a container on which the graphical elements are added. Here is how you could write your initialize function:
public static void initialize() {
frame = new JFrame("Chat program");
frame.setBounds(100, 100, 450, 450);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
JCheckBox chckbxCvbc = new JCheckBox("cvbc");
panel.add(chckbxCvbc);
// Set background color and add panel to the Jframe
panel.setBackground(Color.RED);
frame.getContentPane().add(panel);
}

Related

open same frame when button click in java

i updated the code because many people doesn't understand so write a simple representation for that.
here is the problem whenever i clicked the button it open a new frame but i dont want this it does't open a new frame it remain open the same frame.
code for main frame :
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class JavaProject2_27 {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JavaProject2_27 window = new JavaProject2_27();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public JavaProject2_27() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JButton btnClicked = new JButton("Clicked");
btnClicked.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JavaProject2_28 obj=new JavaProject2_28();
obj.getJavaProject2_28();
}
});
btnClicked.setBounds(150, 99, 89, 23);
frame.getContentPane().add(btnClicked);
}
}
code for the second frame :
import java.awt.EventQueue;
import javax.swing.JFrame;
public class JavaProject2_28 {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JavaProject2_28 window = new JavaProject2_28();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public JavaProject2_28() {
initialize();
}
public void getJavaProject2_28()
{
frame.setVisible(true);
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
snapshot
I was checking your earlier program, still cannot find the implementation of getDataJavaProject2_23(); method in those three classes that you provided.
First of all answer to your question few things to mention:
Use proper naming convention, as a example: JavaProject2_28 this class name didnot make any sense to us or even for you if you look at this after a week or two.
You can divide your program for more classes, as a example: database data handling, GUI and etc.
And another important thing is multiple JFrames for one application is not good because of even if you look at your task bar when running your program you can see there is multiple icons, it is difficult to deal with your application. There is more disadvatages about this. read this to get clear idea. Instead of multiple JFrames you can use one JFrame and multiple JPanel with appropriate layouts.
Answer for your updated question:
whenever i clicked the button it open a new frame but i dont want this
it does't open a new frame it remain open the same frame.
I checked your program it is work fine(after press the button open up the other frame).
You can do some changes that are unnecessary:
Remove this function
public void getJavaProject2_28()
{
frame.setVisible(true);
}
And add frame.setVisible(true); to the initialize() method.
Solution:
Add frame.setVisible(true) to button action.
Like below:
}
});
btnClicked.setBounds(150, 99, 89, 23);
frame.getContentPane().add(btnClicked);
frame.setVisible(true);
}
And in the main frame(which is button button added) change like below:
JButton btnClicked = new JButton("Clicked");
btnClicked.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JavaProject2_28 obj=new JavaProject2_28();
}
});
Also you do not need the main() method in both if you are only open second JFrame in main frame button.
I solved It Please A look :
Parent Class:
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ParentClass {
private JFrame frame;
private int Count;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ParentClass window = new ParentClass();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public ParentClass() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JButton btnClicked = new JButton("Clicked");
btnClicked.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
Count++;
System.out.println("Count = "+Count);
if(Count==1)
{
ChildClass obj=new ChildClass();
obj.ChildClassVisibility();
}
}
});
btnClicked.setBounds(150, 99, 89, 23);
frame.getContentPane().add(btnClicked);
}
}
ChildClass:
import java.awt.EventQueue;
import javax.swing.JFrame;
public class ChildClass {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ChildClass window = new ChildClass();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public ChildClass() {
initialize();
}
public void ChildClassVisibility()
{
frame.setVisible(true);
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Two panels using same height display differently

I'm trying to make a full-screen GUI using Java which, on the JFrame, has 2 JPanel's, one of which only takes roughly 0.10 of the screen width. When I place these panels on the frame, using the same height, they appear to display with a different height on Linux & Mac OS but they appear okay on Windows. Does anybody have any idea on how to make both panels the same height for Linux & Mac OS? I re-made the problem quickly using WindowBuilder for posting here.
package View;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GraphicsDevice;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import controller.ExitActionListener;
import java.awt.event.ActionListener;
public class TestFrame2 {
private JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TestFrame2 window = new TestFrame2();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public TestFrame2() {
initialize();
}
private void initialize() {
frame = new JFrame();
GraphicsDevice device = frame.getGraphicsConfiguration().getDevice();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setUndecorated(true);
frame.setVisible(true);
JPanel panel = new JPanel();
panel.setSize((int)(frame.getWidth()*0.1), frame.getHeight());
panel.setBackground(Color.BLACK);
frame.getContentPane().add(panel);
JPanel panel1 = new JPanel();
panel1.setBackground(Color.RED);
panel1.setSize(frame.getWidth(), frame.getHeight());
frame.getContentPane().add(panel1);
// temporary close button
ActionListener exitActionListener = new ExitActionListener();
JButton exit = new JButton("Exit System");
exit.setBounds(150 ,200, 150, 100);
exit.addActionListener(exitActionListener);
panel1.add(exit);
//Set program as full screen
device.setFullScreenWindow(frame);
}
}

Java - change from Panel1 to Panel2

I wanna create a simple java application, and I have some problems.
This is my main class:
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class MainWindow {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainWindow window = new MainWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MainWindow() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
JButton btnNewButton = new JButton("First B");
panel.add(btnNewButton);
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
SecWindow SW = new SecWindow();
//-----
}
});
}
}
Secound class:
import javax.swing.JButton;
import javax.swing.JPanel;
public class SecWindow {
public SecWindow() {
SecPanel();
}
public void SecPanel() {
JPanel panel2 = new JPanel();
JButton btnNewButton_2 = new JButton("Sec B");
panel2.add(btnNewButton_2);
}
}
How can I do this: when I press the "First B" I wanna delete the first panel and create a new one class SecWindow().
How can I do this: when I press the "First B" I wanna delete the first panel and create a new one class SecWindow().
You should be using a CardLayout. The CardLayout will allow you to swap panels in the frame.
Read the section from the Swing tutorial on How to Use CardLayout for more information and working examples.
The example uses a combo box to swap the panels so you just need to move that code to the ActionListener of your button.
try{
secWindow secondWindow = new secWindow();
secondWindow.frame.setVisible(true);
window.frame.setVisible(false);
} catch (Exception e) {
e.printStackTrace();
This will hide first window and show second one.
You can not completely "delete" object that has main method in it. your app will start and end in main method.
instead you can make new class and transfer main method over there

Java GUI: Image will be overwritten, Path the same -> show it in the frame (image still the same)

I want to show a changing image on my frame. The imagepath is always the same, but the image will be getting overwritten every 10 seconds from another program.
The problem is that the image is not changing when I overwrite it with another image with the same name. So in my understanding: Compiler looks every look in the path and gets the image -> when the image changed it will be changed on the frame!
I hope you understand my problem and somebody could help me.
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class GUI extends JFrame{
public ImageIcon imageBar;
public JLabel labelimage1;
private JLabel labelimage2;
private JLabel bar1 = new JLabel();
private JLabel bar2 = new JLabel();
private JLabel bar3 = new JLabel();
private JLabel bar4 = new JLabel();
private JLabel bar5 = new JLabel();
private JButton buttonBar1 = new JButton("1");
private JButton buttonBar2 = new JButton("2");
private JButton buttonBar3 = new JButton("3");
private JButton buttonBar4 = new JButton("4");
private JButton buttonBar5 = new JButton("5");
private JPanel panel1 = new JPanel();
private JPanel panel2 = new JPanel();
private JPanel panel3 = new JPanel();
private JFrame window = new JFrame("Interface");
public GUI(){
//set the layouts
panel1.setLayout(new GridLayout(1, 2));
panel2.setLayout(new GridLayout(2, 1));
panel3.setLayout(new GridLayout(2, 5));
//place Panel2 and Panel3 in the window
panel1.add(panel2);
panel1.add(panel3);
//----Panel2
//refreshImage();
//----Panel3
panel3.add(buttonBar1); //add the bars 1-5 on panel3
panel3.add(buttonBar2);
panel3.add(buttonBar3);
panel3.add(buttonBar4);
panel3.add(buttonBar5);
//configure the frame
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
window.setSize(800, 400);
window.getContentPane().add(panel1);
}
public void refreshImage() {
panel2.removeAll(); //delete the old panel
//panel2.repaint();
//panel2.revalidate()
DrawImage pan = new DrawImage();
panel2.add(pan);
panel2.add(labelimage2);
}
}
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class DrawImage extends JPanel implements ActionListener{
private ImageIcon image;
public DrawImage(){
image = new ImageIcon("C:\\Users\\usuario\\Desktop\\image.png");
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
image.paintIcon(this, g, 50, 50);
repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
}
import java.io.File;
public class Main {
public static void main(String[] args) {
GUI Interface = new GUI();
while(true)
{
Interface.refreshImage();
try {
Thread.sleep(5000); //wait for 5000ms
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Thank you very much!
The likely cause is Java is caching the image in memory, associated with the source name. So rather then trying to reload the image again, Java simply returns the cached version.
You could use ImageIcon#getImage#flush to force Java to reconstruct the image
Problems
You are calling refreshImage from a Thread other then the Event Dispatching Thread, this could cause issues with the updating of the components and cause rendering artifacts
You are forcefully removing the DrawImage pane and adding a new instance, rather the trying to reload the image
You're calling repaint within the paintComponent method, don't do this...
You should consider using a Swing Timer, which will allow you to schedule a regular update and be notified within the context of the Event Dispatching Thread.
You could provide a simple refresh method which flushes the current ImageIcon and schedule a repaint of the panel...or you could just use a JLabel and save your self the time
An example of Image#flush
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SlideShow {
public ImageIcon imageBar;
public static void main(String[] args) {
new SlideShow();
}
public SlideShow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DrawImage());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawImage extends JPanel {
private ImageIcon image;
public DrawImage() {
image = new ImageIcon("D:\\thumbs\\image.png");
Timer timer = new Timer(5000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
refresh();
}
});
timer.start();
}
public void refresh() {
image.getImage().flush();
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image.getImage(), 0, 0, this);
}
}
}
The problem with this, is because the image data is loaded in a background thread, it won't may no be available when the component is first repainted, which could make the component appear to flicker.
A better approach would be to use ImageIO.read, which will ensure that the image is fully loaded before the method returns, the draw back here is that could cause the application to "pause" momentary as the image is loaded, personally, I'd use the refresh method to stop the the Timer (or set the Timer to non-repeating), start a background Thread to load the image (using ImageIO.read) call repaint (which is thread safe) and restart the Timer...
Your while (true) loop risks typing up the Swing event thread locking your program. If it doesn't do that, then you risk unpredictable threading issues by making Swing calls off of the event Thread. These problems can be solved easily by your using a Swing Timer not a while true loop to do your swapping.
Rather than removing and adding components, why not simply display images as ImageIcons within a single non-swapped JLabel.
To swap images here, simply call setIcon(...) on the JLabel.
For an example of using a Swing Timer to swap images, please check out my answer to a similar question here.
For example:
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class TimerImageSwapper {
public static final String[] IMAGE_URLS = {
"http://imaging.nikon.com/lineup/dslr/d7000/img/sample/img_01.png",
"http://imaging.nikon.com/lineup/dslr/d7000/img/sample/img_02.png",
"http://imaging.nikon.com/lineup/dslr/d7000/img/sample/img_04.png",
"http://imaging.nikon.com/lineup/dslr/d3200/img/sample/img_08.png",
"http://imaging.nikon.com/lineup/dslr/d3200/img/sample/img_05.png",
"http://imaging.nikon.com/lineup/dslr/d3200/img/sample/img_01.png",
"http://imaging.nikon.com/lineup/dslr/d3200/img/sample/img_06.png" };
private ImageIcon[] icons = new ImageIcon[IMAGE_URLS.length];
private JLabel mainLabel = new JLabel();
private int iconIndex = 0;;
public TimerImageSwapper(int timerDelay) throws IOException {
for (int i = 0; i < icons.length; i++) {
URL imgUrl = new URL(IMAGE_URLS[i]);
BufferedImage image = ImageIO.read(imgUrl);
icons[i] = new ImageIcon(image);
}
mainLabel.setIcon(icons[iconIndex]);
new Timer(timerDelay, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
iconIndex++;
iconIndex %= IMAGE_URLS.length;
mainLabel.setIcon(icons[iconIndex]);
}
}).start();
}
public Component getMainComponent() {
return mainLabel;
}
private static void createAndShowGui() {
TimerImageSwapper timerImageSwapper;
try {
timerImageSwapper = new TimerImageSwapper(5 * 1000);
JFrame frame = new JFrame("Timer Image Swapper");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(timerImageSwapper.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Why can i not set the frame frame.setcontentPane(null) for an absolute layout?

I am working on a test example at work and I need to use absolute layout. That is what the boss wants. I found a simple example on line that works and I can put my custom component on it and the frame displays just fine.
But when I try to do it on an already existing form then i get errors. What am I doing wrong?
Code:
package testpak;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import java.awt.*;
import java.awt.event.ActionEvent;
public class FrameDemo {
JFrame frame = new JFrame("Test Custom Component");
JPanel panel = new JPanel();
ImageIcon imageForOne = new ImageIcon(getClass().getResource("stop.jpg"));
JButton MyTestButton = new JButton("",imageForOne);
MyComponent cc = new MyComponent();
//MyComponent cc = new MyComponent(20,50);
FrameDemo() {
setLookFeel();
MyTestButton.setPreferredSize(new Dimension(75, 75));
JButton one = new JButton(new OneAction());
one.setPreferredSize( new Dimension(55, 55));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(null);
frame.pack();
// panel.add(cc);
MyTestButton.setBounds(10, 10, 30, 30);
panel.add(MyTestButton);
one.setBounds(100, 50, 40, 40);
panel.add(one);
frame.add(panel);
frame.setSize(new Dimension(200, 200));
frame.setVisible(true);
}
private void setLookFeel() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
}
public static void main(String[] args) {
FrameDemo fd = new FrameDemo();
}
}
class OneAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public OneAction() {
ImageIcon imageForOne = new ImageIcon(getClass().getResource("help.jpg"));
putValue(LARGE_ICON_KEY, imageForOne);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
Error:
Exception in thread "main" java.awt.IllegalComponentStateException: contentPane cannot be set to null.
at javax.swing.JRootPane.setContentPane(JRootPane.java:620)
at javax.swing.JFrame.setContentPane(JFrame.java:693)
at testpak.FrameDemo.<init>(FrameDemo.java:31)
at testpak.FrameDemo.main(FrameDemo.java:53)
Each top-level container has a content pane that, generally speaking, contains (directly or indirectly) the visible components in that top-level container's GUI.
For more info have a look Using Top-Level Containers
JFrame is a top-level container and you can't set content pane to be null.

Categories

Resources