I made a 840 by 400 frame and added a text field. By default, the java app shrinked only to the size of the text field. I want it fixed to the respective size.
I tried setResizable(false), setExtendedState(), setBounds() with no avail.
Best to use a JPanel as your contentPane or add it to the contentPane, and to override its getPreferredSize() method and then usepack()` on the JFrame. For example:
import java.awt.Dimension;
import javax.swing.*;
#SuppressWarnings("serial")
public class MyPanel extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = 300;
public MyPanel() {
//...
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
MyPanel myPanel = new MyPanel();
JFrame frame = new JFrame("My GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(myPanel);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
One advantage of this is that other classes cannot change MyPanel's size via setSize(...) or setPreferredSize(...).
Try
setPreferredSize(new Dimension(840,400));
If you named your frame you can do
name.setPreferredSize(new Dimension(840,400));
Related
So I am trying to learn how to use card layout and in this sample code I would like to change the size of the frame to a certain size but using setSize does not work.
the following also does not work in the when added to createAndShowGui() function
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setPreferredSize(new Dimension(500,200));
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class MainGui2 extends JPanel {
private CardLayout cardLayout = new CardLayout();
private WelcomePanel welcomePanel = new WelcomePanel(this);
private HomePanel homePanel = new HomePanel();
public MainGui2() {
setLayout(cardLayout);
add(welcomePanel, WelcomePanel.NAME);
add(homePanel, HomePanel.NAME);
}
public void showCard(String name) {
cardLayout.show(this, name);
}
private static void createAndShowGui() {
MainGui2 mainPanel = new MainGui2();
JFrame frame = new JFrame("MainGui2");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
//frame.pack();
frame.setSize(550, 300);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class WelcomePanel extends JPanel {
public static final String NAME = "welcome panel";
private MainGui2 mainGui2;
public WelcomePanel(final MainGui2 mainGui2) {
this.mainGui2 = mainGui2;
add(new JLabel(NAME));
add(new JButton(new AbstractAction("Logon") {
#Override
public void actionPerformed(ActionEvent e) {
mainGui2.showCard(HomePanel.NAME);
}
}));
}
}
class HomePanel extends JPanel {
public static final String NAME = "home panel";
public HomePanel() {
add(new JLabel(NAME));
}
}
I would like to change the size of the frame to a certain size
Don't try to hard code frame sizes.
If you want extra space around the panels then in the constructor of your MainGui2 class you can add:
setBorder( new EmptyBorder(50, 50, 50, 50) );
This will adjust the preferred size of the panel and this size will now be taken into account when the pack() method is used.
am trying to add a button to Jframe from other class but it does not work
public class ShowMain {
public static void main(String[] args) throws Throwable {
//My JFrame
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(600, 400);
frame.setLayout(null);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBackground(Color.GRAY);
}
My other Class
public class Commands {
public static void main(String[] args) throws Throwable {
//JButtons
JButton button1 = new JButton();
button1.setText("");
button1.setBounds(120, 350, 400, 20);
button1.setVisible(true);
}
frame.add(button1) is not working
You've got all your code within two static main methods, meaning that the two classes can hardly interact at all. I suggest that you create true OOP-compliant classes, with instance fields ("state"), instance methods ("behavior"), and that you have one class call the method of another if you wish to change its state. For instance, if the Commands class is to add a JButton, then give your ShowMain class a method for this: public void addCommandButton(JButton button).
Having said this, I wouldn't do this at all if this were my code, but rather would follow a more MVC or "Model-View-Controller" program structure, where one set of classes would represent the program logic, another the user interactions (the listeners) and a 3rd set of classes for the GUI or "view".
For example, run this code that shows how to connect classes without them knowing about the other class (loose coupling):
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ShowMain {
private static void createAndShowGui() {
MainPanel mainPanel = new MainPanel();
JScrollPane scrollPane = new JScrollPane(mainPanel);
CreateActionPanel actionPanel = new CreateActionPanel();
new Controller(actionPanel, mainPanel);
JFrame frame = new JFrame("ShowMain");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(actionPanel, BorderLayout.PAGE_START);
frame.add(scrollPane, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class MainPanel extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = 80;
#Override
public Dimension getPreferredSize() {
Dimension superSz = super.getPreferredSize();
if (isPreferredSizeSet()) {
return superSz;
}
int prefW = Math.max(superSz.width, PREF_W);
int prefH = Math.max(superSz.height, PREF_H);
return new Dimension(prefW, prefH);
}
public MainPanel() {
setBorder(BorderFactory.createTitledBorder("Main Panel"));
}
public void addButtonAction(Action action) {
add(new JButton(action));
// so the button will be displayed properly
revalidate();
repaint();
}
}
class Controller {
public Controller(final CreateActionPanel actionPanel, final MainPanel mainPanel) {
actionPanel.addPropertyChangeListener(CreateActionPanel.ACTION_NAME, pcEvt -> {
mainPanel.addButtonAction(new AbstractAction((String) pcEvt.getNewValue()) {
{
int mnemonic = (int) pcEvt.getNewValue().toString().charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent evt) {
System.out.printf("Button %s pressed!%n", evt.getActionCommand());
}
});
});
}
}
class CreateActionPanel extends JPanel {
public static final String ACTION_NAME = "action name";
private JTextField actionNameField = new JTextField(10);
public CreateActionPanel() {
actionNameField.addActionListener((e -> {
String text = actionNameField.getText();
firePropertyChange(ACTION_NAME, null, text);
actionNameField.selectAll();
}));
add(new JLabel("Button Text to Add:"));
add(actionNameField);
}
}
Like the title says, i am looking to center a 800x600 canvas on a 1920x1080 screen
I want the canvas to be centered in the JFrame
public class Window extends JFrame {
private static final long serialVersionUID = 7045103465799258651L;
Dimension d;
public Window(int w, int h, String title,Launcher launch){
setTitle(title);
d = new Dimension(w,h);
setMinimumSize(d);
setMaximumSize(d);
setPreferredSize(d);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setFocusable(true);
setLocationRelativeTo(null);
add(launch);
launch.start();
}
}
One way:
Give your container a GridBagLayout
Add your component, your drawing JPanel (not Canvas), to the container without use of GridBagConstraints. It will add it to the container by default in a centered position.
If you use BorderLayout like many are telling you, your component will fill the container, which does not seem to be what you're aiming for here.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.*;
public class TestCenterLayout extends JPanel{
private static final long serialVersionUID = 1L;
private static final int PREF_W = 800;
private static final int PREF_H = 600;
private static final Color BACKGROUND = Color.pink;
public TestCenterLayout() {
setBorder(BorderFactory.createTitledBorder("800 x 600 Panel"));
setBackground(BACKGROUND);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Test Center Layout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new GridBagLayout());
frame.getContentPane().add(new TestCenterLayout());
frame.pack();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I try to buid JPanels in a separate class to invoke them separately and add different items on it. Please can you tell me what i am doing wrong?
MyFrame.java
import javax.swing.*;
import java.awt.*;
public class MyFrame extends JFrame {
public static void main(String[] args) {
MyFrame frame = new MyFrame();
frame.setVisible(true);
}
public MyFrame() {
setTitle("MyFrame");
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
JButton testButton = new JButton("Test");
panel.add(testButton);
}
}
MyPanel.java
import javax.swing.*;
import java.awt.*;
class MyPanel extends JPanel {
public MyPanel() {
this.setOpaque(true);
this.setVisible(true);
}
}
You're not adding your panel variable to your JFrame's contentPane.
Add:
public MyFrame() {
setTitle("MyFrame");
// setSize(300, 200); // let's avoid this
setDefaultCloseOperation(EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
JButton testButton = new JButton("Test");
panel.add(testButton);
add(panel); // *** here
pack(); // this tells the layout managers to do their thing
setLocationRelativeTo(null);
setVisible(true);
}
As a side note:
public MyPanel() {
this.setOpaque(true);
this.setVisible(true);
}
JPanels are opaque and visible by default, so your method calls within the MyPanel constructor do nothing useful.
Side note 2: I rarely if ever extend JFrame or any other top level window (with the exception of JApplet if I'm forced to use one of these), since I rarely change the innate behavior of the window. Better I think to create my top level windows (i.e., my JFrames) when needed.
Side note 3: Always strive to start your Swing GUI's on the Swing event thread. So do...
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MyFrame frame = new MyFrame();
frame.setVisible(true);
}
});
}
Edit
You ask:
You wrote lets avoid setting the size.. can you tell me how i can pack it but set a minimum frame size?
I like to override the JPanel's getPreferredSize() method, and have it return a Dimension that makes sense.
For example, you could do something like this to be sure that your GUI is at lest PREF_W by PREF_H in size:
import java.awt.Dimension;
import javax.swing.*;
public class ShowGetPreferredSize extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
#Override
public Dimension getPreferredSize() {
Dimension superSize = super.getPreferredSize();
if (isPreferredSizeSet()) {
return superSize;
}
int w = Math.max(superSize.width, PREF_W);
int h = Math.max(superSize.height, PREF_H);
return new Dimension(w, h);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("ShowGetPreferredSize");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(new ShowGetPreferredSize());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I have a following code ( trying to learn swing and java). I created a ladder using rectangular components using class and placed on the main frame. Everything works okay but if I resize it even slightly, the ShapeManager object (i.e, the ladder) disappears. I don't know what is going on. Any help please.
GUIMain Class:
package mainProg;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.event.*;
import java.awt.*;
public class GUIMain {
static JPanel mainPanel;
static JButton[] newButtons;
static ShapeManager newShape;
private static class BtnEvtHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
//System.exit(0);
JOptionPane.showMessageDialog( null, "WELCOME" );
}
}
private static JButton[] createButtons() {
JButton[] buttonArray= new JButton[2];
buttonArray[0]=new JButton("OK");
buttonArray[1]=new JButton("MOVE");
BtnEvtHandler okButtonHandler= new BtnEvtHandler();
( buttonArray[0]).addActionListener(okButtonHandler);
return buttonArray;
}
private static ShapeManager createShape(int x) {
ShapeManager newContent=new ShapeManager(x);
return newContent;
}
private static JPanel mainContainer() {
JPanel mainPanel= new JPanel();
mainPanel.setSize(400, 400);
return mainPanel;
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(false);
JFrame frame = new JFrame(" DB ");
mainPanel= mainContainer();
mainPanel.setLayout(new BorderLayout(10, 10));
newButtons= createButtons();
newShape= createShape(20);
newButtons[0].setHorizontalAlignment(0);
mainPanel.add(newButtons[0],BorderLayout.PAGE_START);
newButtons[1].setHorizontalAlignment(0);
mainPanel.add(newButtons[1],BorderLayout.PAGE_END);
newShape.setPreferredSize(new Dimension(400, 400));
mainPanel.add(newShape, BorderLayout.LINE_END);
frame.setContentPane(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setLocation(500,200);
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
ShapeManager Class:
package mainProg;
import javax.swing.JPanel;
import java.awt.*;
#SuppressWarnings("serial")
class ShapeManager extends JPanel {
int rectPos;
ShapeManager(int rectPos) {
setPreferredSize(new Dimension(400,400));
this.rectPos=rectPos;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
while (rectPos<150) {
g.setColor(Color.BLUE);
g.drawRect(rectPos+10, rectPos+10, 100, 10);
g.fillRect(rectPos+10, rectPos+10, 100, 10);
rectPos=rectPos+10;
}
}
}
You never reset rectangle position, so after the first paint it remains above 150. You need to reset it after you exit your while loop.
Try this:
g.setColor(Color.BLUE);
int position = rectPos;
while (position<150) {
position += 10;
g.drawRect(position, position, 100, 10);
g.fillRect(position, position, 100, 10);
}