I would like to adjust the size of a JPanel in function of another panel which contains it.
When I run my code, the panel is tiny and centered on the top of the content panel.
So here's my code :
package test;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CodeForStackOverFlow {
public static void main(String[] args) {
Frame frame = new Frame();
}
}
class Frame extends JFrame {
private class Panel extends JPanel {
private JPanel content = new JPanel();
Panel() {
content.setBackground(Color.red);
this.add(content);
}
void adjustSize() {
this.content.setSize(new Dimension(this.getHeight(), this.getHeight()));
}
}
private Panel contentPane = new Panel();
Frame() {
this.setSize(new Dimension(500, 400));
this.setResizable(false);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setContentPane(contentPane);
contentPane.adjustSize();
this.setVisible(true);
}
}
Related
I'm trying to set the size and location of a button on a panel using setBounds. It works when I put the button on the frame and have setLayout(null). But when placed on the panel, the button is always a set size at the top of the panel, if I set the layout to null, the frame just shows up blank.
import javax.swing.JFrame;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
MyFrame cl=new MyFrame("A");
cl.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyFrame extends JFrame implements ActionListener{
MyPanel panel;
Container cont;
JButton b;
public MyFrame(String title) {
super(title);
panel= new MyPanel();
b = new JButton();
b.setBounds(100, 100, 100, 100 );
cont= this.getContentPane();
cont.setLayout(new BorderLayout());
cont.add(panel, BorderLayout.CENTER);
panel.add(b);
this.setLayout(null);
this.setVisible(true);
this.setSize(1000,1000);
}
}
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class MyPanel extends JPanel {
public MyPanel() {
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.BLACK);
}
}
I need to calculate window decorations somehow. So I override JDialog's constructor. But when I call get_decoration_size() it sometimes returns wrong values. And my thought was: window creates later than get_decoration_size() executes(strange, because both in same thread and in same constructor). So I decided to sleep for a second, and it worked, and now decorations always valid.
My question is: is there a way to "join" to the creating process(wait until window is shown by setVisible(true))? If so, it must be something to replace unsafe_sleep(1000).
package swing.window;
import db.db;
import javax.swing.*;
import java.awt.*;
import static swing.util.*;
import static util.util.unsafe_sleep;
public class calc_decor extends JDialog {
{
//some initializations
setLayout(null);
setResizable(false);
JLabel label = new JLabel("Loading...");
add(label);
setxy(label, 3, 3);
fit(label);
setsize(this, label.getWidth() + 100, label.getHeight() + 100);
window_to_center(this);
setVisible(true);//trying to draw
unsafe_sleep(1000);//without that it looks like get_decoratoin_size()
//is called before setVisible(true)
db.sysdecor = get_decoration_size();//trying to get decorations
dispose();
}
private Dimension get_decoration_size() {
Rectangle window = getBounds();
Rectangle content = getContentPane().getBounds();
int width = window.width - content.width;
int height = window.height - content.height;
return new Dimension(width, height);
}
}
I had to assume a lot to create a runnable example.
Here's the result of your getDecorationSize method. The line didn't print until I closed the JDialog.
java.awt.Dimension[width=16,height=39]
And here's the code I used.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class JDialogTest implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new JDialogTest());
}
private JFrame frame;
#Override
public void run() {
frame = new JFrame("JDialog Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(
150, 100, 150, 100));
panel.setPreferredSize(new Dimension(400, 400));
JButton button = new JButton("Open JDialog");
button.addActionListener(new ButtonListener());
panel.add(button);
return panel;
}
public class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
new CalculateDecor(frame, "Spash Screen");
}
}
public class CalculateDecor extends JDialog {
private static final long serialVersionUID = 1L;
public CalculateDecor(JFrame frame, String title) {
super(frame, true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setTitle(title);
JPanel panel = new JPanel(new BorderLayout());
panel.setPreferredSize(new Dimension(200, 200));
JLabel label = new JLabel("Loading...");
label.setHorizontalAlignment(JLabel.CENTER);
panel.add(label);
add(panel);
pack();
setLocationRelativeTo(frame);
setVisible(true);
System.out.println(getDecorationSize());
}
private Dimension getDecorationSize() {
Rectangle window = getBounds();
Rectangle content = getContentPane().getBounds();
int width = window.width - content.width;
int height = window.height - content.height;
return new Dimension(width, height);
}
}
}
I am trying to make a program where I have two JPanels inside a JFrame, one of which contains a canvas. I am trying to find a way to get that canvas to be constantly updating so that I could create something like a game inside the canvas. I was wondering how I could make it so that the JPanel with the canvas in it is constantly refreshing so that you can see when something is changed in the canvas. Here is my code:
package main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main
{
private JFrame frame;
private JPanel mainPanel;
private JPanel gamePanel;
private JPanel sidePanel;
public void setup()
{
frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setVisible(true);
frame.setLocation(100, 50);
mainPanel = new JPanel();
Dimension d = new Dimension(800, 600);
mainPanel.setMaximumSize(d);
mainPanel.setMinimumSize(d);
mainPanel.setPreferredSize(d);
frame.add(mainPanel);
frame.pack();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.X_AXIS));
}
public void setupPanels()
{
gamePanel = new JPanel();
Dimension d = new Dimension(600, 600);
gamePanel.setMaximumSize(d);
gamePanel.setMinimumSize(d);
gamePanel.setPreferredSize(d);
gamePanel.setBackground(Color.RED);
mainPanel.add(gamePanel);
sidePanel = new JPanel();
d = new Dimension(600, 600);
sidePanel.setMaximumSize(d);
sidePanel.setMinimumSize(d);
sidePanel.setPreferredSize(d);
sidePanel.setBackground(Color.BLUE);
mainPanel.add(sidePanel);
}
public void setupGame()
{
GameArea game = new GameArea();
gamePanel.add(game);
game.start();
}
public static void main(String[] args)
{
Main main = new Main();
main.setup();
main.setupPanels();
main.setupGame();
}
How can I make the JMenuBar streak dissapear after the menuitems? I want to put a 2nd menu in the middle of the frame, and it looks weird with this streak.
I tried to set the background to Panel.background but it doesn't work.
import java.awt.*;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.UIManager;
public class SwingMenuDemo extends JPanel {
public SwingMenuDemo(){
setLayout(null);
JMenuBar menuBar = new JMenuBar();
menuBar.setBackground(UIManager.getColor("Panel.background"));
menuBar.setBounds(0, 0, 450, 25);
add(menuBar);
JButton btn1 = new JButton("Menu1");
menuBar.add(btn1);
JButton btn2 = new JButton("Menu2");
menuBar.add(btn2);
JButton btn3 = new JButton("Menu3");
menuBar.add(btn3);
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("SwingMenuDemo");
frame.setPreferredSize(new Dimension(400,400));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(),BoxLayout.PAGE_AXIS));
frame.getContentPane().add(new SwingMenuDemo());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
If you want to create your own "menu" of several JButtons, then don't use JMenu and don't use null layout and setBounds(...) (you should avoid the latter just as a general rule). Instead nest JPanels, each using its own layout manager to allow for simple creation of complex GUI's.
For instance you could create a JPanel to hold the buttons, say called menuPanel, give it a new GridLayout(1, 0) layout, meaning it will hold a grid of components in 1 row, and a variable number of columns (that's what the 0 means). Then put your buttons in that.
Then place that JPanel into another JPanel that uses say FlowLayout.LEADING, 0, 0) as its layout -- it will push all its components to the left.
Then make the main GUI use a BorderLayout and add the above panel to it's top in the BorderLayout.PAGE_START position. For example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.*;
#SuppressWarnings("serial")
public class SwingMenuDemo2 extends JPanel {
private static final String[] MENU_TEXTS = {"Menu 1", "Menu 2", "Menu 3"};
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
public SwingMenuDemo2() {
JPanel menuPanel = new JPanel(new GridLayout(1, 0));
for (String menuText : MENU_TEXTS) {
menuPanel.add(new JButton(menuText));
}
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
topPanel.add(menuPanel);
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
SwingMenuDemo2 mainPanel = new SwingMenuDemo2();
JFrame frame = new JFrame("Swing Menu Demo 2");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
You can do that with
menuBar.setBorderPainted(false);
I have written a code that has a label and a button in a frame. I have also changed the background but it never changes.
import javax.swing.*;
import java.awt.*;
import javax.swing.border.*;
public class Frames
{
JFrame Main_Menu=new JFrame("MAIN MENU");JFrame CIRCUMFERENCE=new JFrame("CIRCUMFERENCE");
JFrame AREA=new JFrame("AREA");JFrame PERIMETER=new JFrame("PERIMETER");JFrame SETS=new JFrame("SETS");
JFrame FUNDAMENTAL_OPRATIONS=new JFrame("FUNDAMENTAL OPRATIONS");JFrame POWER_AND_ROOTS=new JFrame("POWER_AND_ROOTS");
void Main_Menu()
{
JPanel contentPane = (JPanel) Main_Menu.getContentPane();
contentPane.setLayout(new BorderLayout(10,10));
contentPane.setBorder(new EmptyBorder(300, 150, 300, 150));
contentPane.setLayout(new GridLayout(4, 4));
JPanel buttonPanel = new JPanel(new GridLayout(8,8));
contentPane.add(Labels.Main_MENU,BorderLayout.NORTH);
contentPane.add(Buttons.SETS,BorderLayout.SOUTH);
Main_Menu.setBackground(Color.YELLOW);
Main_Menu.pack();
Main_Menu.setVisible(true);
}
}
You should actually be setting the background color of the content pane via getContentPane().setBackground(Color.YELLOW):
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
public class Frames extends JFrame {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new Frames();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Frames() {
setSize(new Dimension(100, 100));
setTitle("MAIN MENU");
getContentPane().setBackground(Color.YELLOW);
setVisible(true);
}
}
Also, consider using variable naming conventions; for instance, Main_Menu should be named as mainMenu.