How change background color of JFrame [duplicate] - java

This question already has answers here:
Java JFrame background color not working
(4 answers)
Closed 8 years ago.
I can't change the background color of a JFrame, or of a JPanel inside the JFrame, this is my code:
public class MyFrame extends JFrame {
public MyFrame(){
setSize(600,600);
setResizable(false);
panel = new MyPanel();
panel.setBackground(Color.BLACK);
//getContentPane().setBackground(Color.BLACK); doesn't work
getContentPane().add(panel);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent ev){
System.exit(-1);
}
public void windowClosed(WindowEvent ev){
System.exit(-1);
}
});
}
public void paint(Graphics g){
super.paint(g);
g.clearRect(0,0,600,600);
synchronized (this){
if (positions!=null){
for (int i=0; i<positions.length; i++){
P2d p = positions[i];
//int x0 = (int)(180+p.x*180);
//int y0 = (int)(180-p.y*180);
g.drawOval((int)p.x,(int)p.y,5,5);
}
}
}
}
}
i have tried in several ways, but I can not change the color, it's always white, how i can do?

Try this one. Draw a rectangle filled with your background color.
use SwingUtilities.invokeLater() or EventQueue.invokeLater()
use paintComponent() method for custom painting
don't draw on JFrame directly.
use setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) to close the JFrame
Sample code:
public class MyFrame extends JFrame {
public MyFrame() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
setSize(new Dimension(600, 600));
setResizable(false);
JPanel panel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.clearRect(0, 0, 600, 600);
Color prevColor = g.getColor();
g.setColor(Color.BLUE); // background color
g.fillRect(0, 0, 600, 600); // fill a rectangle with background color
g.setColor(prevColor);
// your custom painting
...
}
};
getContentPane().add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
});
}
}

Not sure if this will work for you but try
JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
or you could try setting the colour in the JFrame and leaving the colour out of the pannel
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("MyFirstFrame");
frame.setBackground(Color.BLACK);
frame.setLocation(0,0);
frame.setSize(150,150);

Check out this answer to change background color
import javax.swing.JFrame;
import java.awt.Color;
import java.awt.EventQueue;
public class ColoredFrame {
public static void main( String[] args ) {
EventQueue.invokeLater( new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame( "TestFrame" );
frame.getContentPane().setBackground( Color.PINK );
//frame contains nothing, so set size
frame.setSize( 200, 200 );
frame.setVisible( true );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
} );
}
}
Reference of Robin's answer.

As for your MyPanel it looks like you didn't set the size so atm it is not visible.
And for your jFrame since you override paint, why not try setting g.setBackground(Color.BLACK);.

Related

Why is JPanel size is wrong?

There is constructor of class extending JFrame:
import java.awt.*;
import javax.swing.*;
public class ChessFrame extends JFrame {
public ChessFrame () {
setSize(520, 520);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(1, 1));
// Add components
getContentPane().add(new Board());
pack();
setVisible(true);
}
}
And class extending JPanel:
import javax.swing.*;
public class Board extends JPanel {
public Board() {
setSize(new Dimension(520, 520));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillRect(0, 0, 520, 520);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(520, 520);
}
}
As a result rectangle smaller then 520x520.
Size of black rectangle is about 496x510. There is more:
getWidth() and getHegiht() written inside the Board class, returns 0 and 0 (so size of this JPanel into JFrame is 0x0)
If I remove pack(), size of frame becomes 496x510 (black rectangle size)
It's actually copypaste of official java tutorial: https://docs.oracle.com/javase/tutorial/uiswing/painting/step2.html.
Do I do something wrong or it's something related with java? If it's second, why does this happen?
Any help would be appreciated.
This example only tries to establish the panel size once the frame (and panel) are visible on-screen. It returns the exact size (300 pixels) set in the code.
import java.awt.*;
import javax.swing.*;
public class ChessBoard extends JPanel {
int size = 300;
JLabel sizeLabel = new JLabel();
ChessBoard() {
setBackground(Color.CYAN);
setLayout(new GridBagLayout());
add(sizeLabel);
}
public void showSize() {
sizeLabel.setText(String.format("%1sx%1s", getWidth(), getHeight()));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(size,size);
}
public static void main(String[] args) {
Runnable r = () -> {
ChessBoard cb = new ChessBoard();
JFrame f = new JFrame(cb.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(cb);
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
// delay showing size until app. is on-screen
Runnable r1 = cb::showSize;
SwingUtilities.invokeLater(r1);
};
SwingUtilities.invokeLater(r);
}
}

Java Drawing to a JPanel (debugging)

I'm trying to draw a basic object to a JPanel
although it doesn't seem to be working.
I'm certain I am doing something wrong with where the paint method
is being called
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
public class testGui {
static colors gc_colors;
static gui gc_gui;
public static void main(String[] args) {
gc_colors = new colors();
gc_gui = new gui();
gc_gui.cv_frame.setVisible(true);
}
public static class colors {
Color cv_ltGrey;
Color cv_mdGrey;
Color cv_dkGrey;
public colors() {
cv_ltGrey = Color.decode("#DDDDDD");
cv_mdGrey = Color.decode("#CCCCCC");
cv_dkGrey = Color.decode("#111111");
}
}
public static class gui {
JFrame cv_frame;
JPanel cv_panel;
JPanel cv_content;
public gui() {
cv_frame = new JFrame();
cv_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cv_frame.setTitle("Test GUI");
cv_frame.setSize(600, 400);
cv_frame.setLayout(new FlowLayout());
cv_panel = new JPanel();
cv_panel.setBackground(gc_colors.cv_ltGrey);
cv_panel.setPreferredSize(new Dimension(500, 300));
cv_frame.add(cv_panel);
cv_content = new content();
cv_panel.add(cv_content);
}
}
public static class content extends JPanel {
public void paint(Graphics graphic) {
super.paint(graphic);
draw(graphic);
}
public void update() {
repaint();
}
public void draw(Graphics graphic) {
Graphics2D graphic2D = (Graphics2D) graphic;
graphic2D.setPaint(gc_colors.cv_ltGrey);
graphic2D.fillRect(10, 10, 100, 100);
}
}
}
I have a class for my gui which I am adding a JPanel to (a light grey one).
Which I am then trying to add my drawing to using a JPanel extended class
called content.
When I run it though it seems to create the grey JPanel which I want but
the drawing is just a tiny white square and I'm not sure why.
So, you content panel has a default preferred size of 0x0, FlowLayout honours the preferredSize of its components (with a little margin), hence the reason why you have a nice little small white rectangle.
What you need to do is override the getPreferredSize method of the content panel and return a suitable size, for example
public static class content extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(120, 120);
}
public void paint(Graphics graphic) {
super.paint(graphic);
draw(graphic);
}
public void update() {
repaint();
}
public void draw(Graphics graphic) {
Graphics2D graphic2D = (Graphics2D) graphic;
graphic2D.setPaint(gc_colors.cv_ltGrey);
graphic2D.fillRect(10, 10, 100, 100);
}
}
I've decided to just leave out the second JPanel altogether.
It was too much of a hassle to put the JPanel inside of another JPanel
so instead I am only going to use a single JPanel
public static class gui {
JFrame cv_frame;
JPanel cv_panel;
JPanel cv_content;
public gui() {
cv_frame = new JFrame();
cv_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cv_frame.setTitle("Test GUI");
cv_frame.setSize(600, 400);
cv_frame.setLayout(new FlowLayout());
cv_content = new content();
cv_content.setBackground(gc_colors.cv_ltGrey);
cv_content.setPreferredSize(new Dimension(500, 300));
cv_frame.add(cv_content);
}
}

Pass in JFrame to change brightness?

I am trying to make a popup over my JFrame in Swing. I have made it so that the popup will be layered over the old JFrame and disable the old one by passing in the JFrame and then .disable(). However, i am also trying to make the frame behind darken to show that it is disabled.
I found this:
stackoverflow - Change brightness of JFrame
But how do i use it to lower the brightness of the JFrame that i have as a parameter just before i disable it? Something like darken(frame) and it lowers it using the function darken(JFrame frame). Thanks!
In fact, I'm going to make my comment an answer:
To show a window over another window, and disable the lower window, make the upper window a modal JDialog, and pass the lower window in as its parent.
One way to dim a top-level window is to get its glass pane, set it visible, and draw a semi-opaque grey color over it.
Here's my test of concept code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Dialog.ModalityType;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class DimView {
protected static final Color GP_COLOR = new Color(0, 0, 0, 30);
private static void createAndShowGui() {
final JFrame frame = new JFrame("DimView");
final JPanel glassPanel = new JPanel() {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(GP_COLOR);
g.fillRect(0, 0, getWidth(), getHeight());
};
};
glassPanel.setOpaque(false);
frame.setGlassPane(glassPanel);
JPanel mainPanel = new JPanel();
mainPanel.setPreferredSize(new Dimension(400, 400));
mainPanel.setBackground(Color.pink);
mainPanel.add(new JButton(new AbstractAction("Push Me") {
#Override
public void actionPerformed(ActionEvent evt) {
glassPanel.setVisible(true);
JDialog dialog = new JDialog(frame, "Dialog",
ModalityType.APPLICATION_MODAL);
dialog.add(Box.createRigidArea(new Dimension(200, 200)));
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
glassPanel.setVisible(false);
}
}));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Swing Canvas not painting as expected (or at all)

public class TerrisView extends JFrame {
public Canvas canvas;
public TerrisView(String title) {
super(title);
canvas = new Canvas();
canvas.setSize(300, 400);
canvas.setBackground(Color.WHITE);
// setSize(300, 400);
this.add(canvas, BorderLayout.CENTER);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
paint();
}
public void paint() {
// this.createBufferStrategy(2);
// Graphics gp=getBufferStrategy().getDrawGraphics();
// gp.setColor(Color.RED);
// gp.fillRect(100, 100, 50, 50);
// getBufferStrategy().show();
Graphics gp = canvas.getGraphics();
gp.setColor(Color.BLACK);
gp.fillRect(0, 0, 10, 10);
}
}
Why does it fail to draw the Rect on the canvas? What is wrong with the code?
Don't mix Swing with AWT components without good reason.
In this case:
Extend JComponent instead of Canvas
Override paintComponent(Graphics) instead of paint(Graphics)
Before I formatted that code, I failed to notice that paint() was not an override, and this classic..
Graphics gp = canvas.getGraphics();
Don't do that with components. Use the Graphics object that is passed to the methods mentioned in point 2, and paint when told to do so.
This answer is already accepted, but I could not resist reviewing and cleaning up the source to make an SSCCE, as well as add a few more tweaks. See comments in code for further tips.
import java.awt.*;
import javax.swing.*;
public class TerrisView {
public JComponent canvas;
public TerrisView(String title) {
// Don't extend frame, just use one
JFrame f = new JFrame(title);
canvas = new JComponent() {
#Override // check this is a real method
public void paintComponent(Graphics g) {
super.paintComponent(g);
// paint the BG - automatic for a JPanel
g.setColor(getBackground());
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(Color.BLACK);
// make it dynamic, changing with the size
int pad = 10;
g.fillRect(pad, pad, getWidth()-(2*pad), getHeight()-(2*pad));
}
};
// layout managers are more likely to respect the preferred size
canvas.setPreferredSize(new Dimension(300, 400));
canvas.setBackground(Color.ORANGE);
f.add(canvas, BorderLayout.CENTER);
f.pack();
// nice tweak
f.setMinimumSize(f.getSize());
// see http://stackoverflow.com/a/7143398/418556
f.setLocationByPlatform(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
public static void main(String[] args) {
// start/alter Swing GUIs on the EDT
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TerrisView("Terris View");
}
});
}
}

Drawing a static image over the viewport of a JScrollPane

I am trying to draw a red square over a JScrollPane. The code I have below does an okay job of this, but sometimes when I scroll the viewport too fast, the red square jumps up or down.
This struck me as odd since the JScrollPane itself is stationary, so I assumed Swing would not try to move around the components painted within it. I'm guessing that what's actually happening is that the the red square gets associated with viewport, which display graphics that do move.
Anyway, how do I prevent the red square from jumping around and successfully draw a red square over the list? Maybe I'm taking the wrong approach altogether.
package components;
import java.awt.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.event.*;
#SuppressWarnings("serial")
public class DialogWithScrollPane extends JFrame {
public DialogWithScrollPane() {
super();
setResizable(false);
Container pane = getContentPane();
Vector<Object> listOfStuff = new Vector<Object>();
for (int i = 0; i < 100; i++) {
listOfStuff.add(Integer.toString(i));
}
final JScrollPane scrollPane = new JScrollPane() {
public void paint(Graphics g) {
System.out.println("JScrollPane.paint() called.");
super.paint(g);
g.setColor(Color.red);
g.fillRect(20, 50, 100, 200);
}
};
JList list = new JList(listOfStuff) {
public void paint(Graphics g) {
System.out.println("JList.paint() called.");
super.paint(g);
// Well, I could do this...
//
// scrollPane.repaint();
//
// ...and it would solve the problem, but it would also result in an
// infinite recursion since JScrollPane.paint() would call this
// function again.
}
};
// Repaint the JScrollPane any time the viewport is moved or an item in the
// list is selected.
scrollPane.getViewport().addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
scrollPane.repaint();
}
});
list.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
scrollPane.repaint();
}
});
scrollPane.setViewportView(list);
pane.add(scrollPane);
setMinimumSize(new Dimension(300, 300));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocation(500, 250);
setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new DialogWithScrollPane();
}
});
}
}
The JScrollPane should be painting behind the JViewport which should be painting behind the list. I'm guessing that this is only working because you're overriding paint and not paintComponent and calling repaint on the JScrollPane all the time so that it paints itself again after its components are painted.
Perhaps you want to use a JLayeredPane and have it hold the JScrollPane, and paint on it.
edit: or the glasspane as I now see that mre suggests, but I'm afraid if you do that, and set the glasspane visible, you'll lose the ability to interact with the underlying scrollpane.
Edit 2
For e.g.,
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.Vector;
import javax.swing.*;
#SuppressWarnings("serial")
public class DialogWithScrollPane2 extends JFrame {
public DialogWithScrollPane2() {
super();
//setResizable(false);
final JPanel pane = (JPanel) getContentPane();
Vector<Object> listOfStuff = new Vector<Object>();
for (int i = 0; i < 100; i++) {
listOfStuff.add(Integer.toString(i));
}
final JScrollPane scrollPane = new JScrollPane();
JList list = new JList(listOfStuff);
scrollPane.setViewportView(list);
final JPanel blueRectPanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.blue);
g.fillRect(20, 50, 100, 200);
}
};
blueRectPanel.setOpaque(false);
final JLayeredPane layeredPane = new JLayeredPane();
layeredPane.add(scrollPane, JLayeredPane.DEFAULT_LAYER);
layeredPane.add(blueRectPanel, JLayeredPane.PALETTE_LAYER);
layeredPane.addComponentListener(new ComponentAdapter() {
private void resizeLayers() {
final JViewport viewport = scrollPane.getViewport();
scrollPane.setBounds(layeredPane.getBounds());
blueRectPanel.setBounds(viewport.getBounds());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
blueRectPanel.setBounds(viewport.getBounds());
}
});
}
#Override
public void componentShown(ComponentEvent e) {
resizeLayers();
}
#Override
public void componentResized(ComponentEvent e) {
resizeLayers();
}
});
pane.add(layeredPane);
setPreferredSize(new Dimension(300, 300));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocation(500, 250);
setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new DialogWithScrollPane2();
}
});
}
}

Categories