Java Swing graphics resolution and dimensions distorted in JDK10 - java

I've updated the compiler version for a basic Swing project from JDK1.8 to JDK10. This has resulted in poorer image resolution, and sizes/dimensions of JPanels now appear different. See screenshots for J8 vs J10:
Java 8:
Java 10:
Below is the entire app code:
package com.nickjwhite.test;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class App {
//UI objects
private JFrame frame;
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
new App();
}
public App() {
try {
//
//
//Initialise Parent Frame
//
//
setFrame(new JFrame());
getFrame().setSize(1200,800); // Dimensions of non-Maximised frame
getFrame().setTitle("Test App");
getFrame().setLocationRelativeTo(null); // Centre the frame
getFrame().setExtendedState(JFrame.MAXIMIZED_BOTH); // Maximise the frame on launch
getFrame().setIconImage(ImageIO.read(getClass().getClassLoader().getResourceAsStream("test.jpg")));
getFrame().setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Kill process if window closed
getFrame().setVisible(true);
//
//
//Main content panel
//
//
contentPane = new JPanel(new GridBagLayout());
contentPane.setBackground(Color.decode("#2e3131"));
getFrame().setContentPane(contentPane);
//
//
//MenuPanel
//
//
JPanel menuPanel = new JPanel();
//Initialise Menu
// Title Background
//
JPanel menuTitleBg = new JPanel();
menuTitleBg.setLayout(new GridBagLayout());
menuTitleBg.setBackground(Color.decode("#d5b8ff"));
GridBagConstraints menuTitleBg_constraints = new GridBagConstraints();
menuTitleBg_constraints.fill = GridBagConstraints.BOTH;
menuTitleBg_constraints.gridx = 0;
menuTitleBg_constraints.gridy = 0;
menuTitleBg_constraints.weightx = 1;
menuTitleBg_constraints.weighty = 0;
menuPanel.add(menuTitleBg, menuTitleBg_constraints);
JLabel testImage = new JLabel();
GridBagConstraints testImage_constraints = new GridBagConstraints();
testImage_constraints.insets = new Insets(10, 10, 10, 10);
testImage_constraints.gridx = 0;
testImage_constraints.gridy = 0;
testImage.setSize(new Dimension(80,80));
testImage.setOpaque(false);
menuTitleBg.add(testImage,testImage_constraints);
try {
BufferedImage img = ImageIO.read(App.class.getClassLoader().getResourceAsStream("test.jpg"));
Image dimg = img.getScaledInstance(testImage.getWidth(), testImage.getHeight(), Image.SCALE_SMOOTH);
testImage.setIcon(new ImageIcon(dimg));
} catch (IOException e) {
e.printStackTrace();
}
menuPanel.setLayout(new GridBagLayout());
menuPanel.setBackground(Color.decode("#9b59b6"));
menuPanel.setPreferredSize(new Dimension(400, (int) (contentPane.getPreferredSize().height)));
menuPanel.setMinimumSize(new Dimension(400,10));
GridBagConstraints gbc_panel = new GridBagConstraints();
gbc_panel.fill = GridBagConstraints.BOTH;
gbc_panel.gridx = 0;
gbc_panel.gridy = 0;
gbc_panel.weightx = 0;
gbc_panel.weighty = 1;
JScrollPane menuScrollPane = new JScrollPane(menuPanel);
menuScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
menuScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
menuScrollPane.setPreferredSize(new Dimension(400, (int) (contentPane.getPreferredSize().height)));
contentPane.add(menuScrollPane , gbc_panel);
//
//
//Action Window Panel
//
//
JPanel actionWindow = new JPanel();
actionWindow.setLayout(new GridBagLayout());
actionWindow.setBackground(Color.decode("#2e3131"));
GridBagConstraints gbc_actionWindow = new GridBagConstraints();
gbc_actionWindow.anchor = GridBagConstraints.EAST;
gbc_actionWindow.fill = GridBagConstraints.BOTH;
gbc_actionWindow.gridx = 1;
gbc_actionWindow.gridy = 0;
gbc_actionWindow.weightx = 1;
gbc_actionWindow.weighty = 1;
contentPane.add(actionWindow, gbc_actionWindow);
} catch (IOException e) {
e.printStackTrace();
}
}
public JFrame getFrame() {
return frame;
}
public void setFrame(JFrame frame) {
this.frame = frame;
}
}
I need to continue compiling with JDK10 for this project, but need the GUI to reflect the JDK8 output, preferably acheiving this without having to adjust the menuPanel Preferred Size, or the testImage dimenstions.
Anyone know what's caused this?

Related

Java Component alignment to top left corner

I want to align my two of my components to the top left corner of the window.
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
public class MainFrame extends JFrame {
public MainFrame() {
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel gridbagPanel = new JPanel();
this.setLayout(new BorderLayout());
gridbagPanel.setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
JLabel nameLabel = new JLabel(player.getName());
nameLabel.setHorizontalAlignment(SwingConstants.CENTER);
nameLabel.setFont(new Font("Serif",Font.PLAIN,24));
mainPanel.add(nameLabel, BorderLayout.NORTH);
JLabel money = new JLabel("Pinigai: "+new Integer(player.getMoney()).toString());
gc.gridx = 0;
gc.gridy = 0;
gc.anchor = GridBagConstraints.PAGE_START;
gc.insets = new Insets(2,0,0,2);
gridbagPanel.add(money,gc);
JLabel job = new JLabel("Darbas: "+new Integer(player.getSkin()).toString());
gc.gridx = 0;
gc.gridy = 1;
gc.insets = new Insets(2,0,0,2);
gc.anchor = GridBagConstraints.LINE_START;
gridbagPanel.add(job, gc);
mainPanel.setBorder(new EmptyBorder(10,10,10,10));
mainPanel.add(gridbagPanel,BorderLayout.WEST);
add(mainPanel);
getContentPane().revalidate();
}
}
It currently looks like this:
And I would like the lines with numbers in the top left corner.
Note that I'm aware that both JFrame("this" class) and the mainPanel are using BorderLayouts.
Another non-related question: When should I create a new GridBagConstraints object? Why can't I just store one in a private instance variable for all usage needed?
The beauty of GridBagLayout, is that column/row sizes are not fixed (ie, not every row/column has to be the same size, like in GridLayout)
You can "encourage" certain components to occupy more space within their given area then others.
Things like weightx and weighty describe how much of the available space a row/column should occupy. Add in the NORTHWEST anchor constraint and you should begin to see the desired effect.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class MainFrame extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new MainFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public MainFrame() {
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel gridbagPanel = new JPanel();
this.setLayout(new BorderLayout());
gridbagPanel.setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
JLabel nameLabel = new JLabel("Bebras");
nameLabel.setHorizontalAlignment(SwingConstants.CENTER);
nameLabel.setFont(new Font("Serif", Font.PLAIN, 24));
mainPanel.add(nameLabel, BorderLayout.NORTH);
JLabel money = new JLabel("Pinigai: " + new Integer(66484).toString());
gc.gridx = 0;
gc.gridy = 0;
gc.anchor = GridBagConstraints.NORTHWEST;
gc.insets = new Insets(2, 0, 0, 2);
gridbagPanel.add(money, gc);
JLabel job = new JLabel("Darbas: " + new Integer(126).toString());
gc.gridx = 0;
gc.gridy = 1;
gc.insets = new Insets(2, 0, 0, 2);
gc.anchor = GridBagConstraints.NORTHWEST;
gc.weightx = 1;
gc.weighty = 1;
gridbagPanel.add(job, gc);
mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
mainPanel.add(gridbagPanel, BorderLayout.WEST);
add(mainPanel);
getContentPane().revalidate();
}
}
Normally, I would add a "filler" component into the component, using it to push all the other components to where I want them, but this will come down to what it is you want to achieve.
Take a look at How to use GridBagLayout for more details
Im more of a fan of Box Layouts to achieve this type of static positioning in swing. see the example below:
import java.awt.Dimension;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class main extends JFrame {
public static void main(String[] args) throws InterruptedException {
main m = new main();
m.setVisible(true);
}
public main() {
// setup stuff
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setBounds(100, 100, 500, 500);
// this is the panel I will add to the frame
JPanel innerPanel = new JPanel();
// give it a Y axis to stuff is added top to bottom
innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.Y_AXIS));
// this is a temp panel ill used to add the labels
JPanel tPanel = new JPanel();
// its an x axis to add stuff left to right
tPanel.setLayout(new BoxLayout(tPanel, BoxLayout.X_AXIS));
// create and add a label to the temp panel
JLabel label = new JLabel("Some text");
tPanel.add(label);
// use our stretchy glue to fill the space to the right of the label
tPanel.add(Box.createHorizontalGlue());
// add the temp panel to the inner panel
innerPanel.add(tPanel);
// create a spacer with 0 width and 10 height
innerPanel.add(Box.createRigidArea(new Dimension(0, 10)));
// reinitialize the temp panel for another label
tPanel = new JPanel();
tPanel.setLayout(new BoxLayout(tPanel, BoxLayout.X_AXIS));
label = new JLabel("Some other text");
// add the other label to the temp panel
tPanel.add(label);
// more stretchy glue
tPanel.add(Box.createHorizontalGlue());
// add the temp panel
innerPanel.add(tPanel);
// add verticle stretchy glue to fill the rest of the space below the
// labels
innerPanel.add(Box.createVerticalGlue());
// add to the frame
this.add(innerPanel);
}
}

GridBagLayout Java

Hi again i've put in my original code just to let you see what i was talking about for the GridBagConstrainsts thats i was trying to put each image to be stuck to the south of the panel immediately next to each other
package prototype;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
//Declare the class which extends JFrame and
//implements ActionListener to enable bottons to respond whenever clicked or selected
public class Master extends JFrame implements ActionListener {
//create the bottons visible by the user
JButton check = new JButton("");
JButton playList = new JButton("");
JButton update = new JButton("");
JButton quit = new JButton("");
JCheckBox tick = new JCheckBox("Tick");
JPanel top = new JPanel();
public static void main(String[] args) {
//declare object of the class
Master jf = new Master();
}
public Master() {
setLayout(new BorderLayout());
setSize(1050, 400);
setTitle("Master");
// close application only by clicking the quit button
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//show the frame in the middle of the screen when run
setLocationRelativeTo(null);
top.add(new JLabel("Select an option by clicking one of the buttons below"));
add("North", top); // add the text above to the upper part of the frame (North)
JPanel bottom = new JPanel();
bottom.setLayout(new GridBagLayout());
bottom.add(check);
check.addActionListener(this);
bottom.add(playList);
playList.addActionListener(this);
bottom.add(update);
update.addActionListener(this);
bottom.add(quit);
quit.addActionListener(this);
add("South", bottom);
//make the frame non resizable but visible
setResizable(true);
setVisible(true);
try{
Image img = ImageIO.read(getClass().getResource("gui/Exit.png"));
Image resize = img.getScaledInstance(290, 180, 18);
quit.setIcon(new ImageIcon(resize));
img = (bottom, new JLabel("NAME"), 0,0,1,1, GridBagConstraints.SOUTH);
}catch(Exception e){
}
try{
Image img = ImageIO.read(getClass().getResource("gui/Untitled.png"));
Image resize = img.getScaledInstance(290, 180, 18);
check.setIcon(new ImageIcon(resize));
}catch(Exception e){
}
try{
Image img = ImageIO.read(getClass().getResource("gui/CPL.png"));
Image resize = img.getScaledInstance(290, 180, 18);
playList.setIcon(new ImageIcon(resize));
}catch(Exception e){
}
try{
Image img = ImageIO.read(getClass().getResource("gui/UpdateLib.png"));
Image resize = img.getScaledInstance(290, 180, 18);
update.setIcon(new ImageIcon(resize));
}catch(Exception e){
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == check) {
new CheckLibrary();
} else if (e.getSource() == update) {
new UpdateLibrary();
} else if (e.getSource() == quit) {
System.exit(0);
} else if (e.getSource() == playList) {
new CreatePlaylist();
}
}
}
For that purposes you need to use anchor and weighty properties of GridBagConstraints.
In next example I set JTextField to the south:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class Example extends JFrame {
public Example (){
JTextField f = new JTextField(20);
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.SOUTHEAST;
c.weighty = 1;
add(f,c);
}
public static void main(String...strings ){
Example e = new Example();
e.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
e.pack();
e.setLocationRelativeTo(null);
e.setVisible(true);
}
}
If you need to fill all horizontal space by component add next :
c.weightx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
For Image you can use JLabel instead of JTextField in my example :
JLabel l = new JLabel(new ImageIcon(getClass().getResource(PATH_TO_IMAGE)));
You cannot add an image directly to a JPanel. What you can do instead is to set the image to be the image icon of a JPanel or JLabel and add that to whatever you're trying to make.

How do I get my JButton to both switch the JPanel and close the JFrame?

I've managed to get the JButton buttonOne in class Database to switch panels, but at the same time it's opening a new JFrame to do this. How can I change it so it just changes the JFrame panel without having to open another JFrame? I have a feeling I could do this if I could return both JPanel and JFrame but I don't know how to do so. Thanks for any help :
First class, with the JFrame and the JPanel that is being switched to on click of 'buttonOne' :
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDatabaseFarme;
import javax.swing.JLabel;
public class Database{
//Running the GUI
public static void main(String[] args) throws IOException {
Database gui2 = new Database();
gui2.mainPanel();
}
JDatabaseFarme mainPanel() throws IOException {
// GridBagLayout/Constraint
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(15,15,15,15);
final JDatabaseFarme DatabaseFarme = new JDatabaseFarme("Lohn Jocke and the Quest for Qualia"); //Had to set DatabaseFarme to final for the action listener
//JPanel panel = new JPanel(new GridBagLayout()); (??)
final JComponent panel = new JLabel(new ImageIcon(ImageIO.read(new File("res/FinalBG.png")))); //Had to set panel to final for the action listener
panel.setLayout(new GridBagLayout());
////// Creating JButtons/Icons for the buttons ////
BufferedImage buttonIcon = ImageIO.read(new File("res/PlayGame.png"));
JButton button = new JButton ("", new ImageIcon(buttonIcon));
BufferedImage buttonIcon2 = ImageIO.read(new File("res/Scoreboard.png"));
JButton buttonTwo = new JButton ("", new ImageIcon(buttonIcon2));
BufferedImage buttonIcon3 = ImageIO.read(new File("res/SQLs.png"));
JButton buttonThree = new JButton ("",new ImageIcon(buttonIcon3));
// Scoreboard button ActionListener
buttonThree.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
//removed some code from here
try {
panel.setVisible(false);
SQLsPanel a = new SQLsPanel();
JComponent SQLsPanel = a.SQLsPanel();
DatabaseFarme.add(SQLsPanel);
DatabaseFarme.getContentPane().add(BorderLayout.CENTER, SQLsPanel);
SQLsPanel.setVisible(true);
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
////// Creating/adding button rollover images /////
BufferedImage buttonIcon1b = ImageIO.read(new File("res/PlayGameHigh.png"));
button.setRolloverIcon(new ImageIcon(buttonIcon1b));
BufferedImage buttonIcon2b = ImageIO.read(new File("res/ScoreboardHigh.png"));
buttonTwo.setRolloverIcon(new ImageIcon(buttonIcon2b));
BufferedImage buttonIcon3b = ImageIO.read(new File("res/SQLsHigh.png"));
buttonThree.setRolloverIcon(new ImageIcon(buttonIcon3b));
// Setting up GridBagConstraints for each JButton
gbc.weightx=1;
gbc.weighty=0;
gbc.gridx=0;
gbc.gridy=0;
gbc.anchor = GridBagConstraints.CENTER;
panel.add(button, gbc); //PLAY GAME
gbc.weightx=1;
gbc.weighty=0;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridx=0;
gbc.gridy=1;
panel.add(buttonTwo,gbc); //SCOREBOARD
gbc.weightx=1;
gbc.weighty=0;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridx=0;
gbc.gridy=2;
panel.add(buttonThree,gbc); //SQLS
// JDatabaseFarme settings
DatabaseFarme.add(panel);
DatabaseFarme.getContentPane().add(BorderLayout.CENTER, panel);
DatabaseFarme.setSize(860,500);
DatabaseFarme.setLocationRelativeTo(null);
DatabaseFarme.setDefaultCloseOperation(JDatabaseFarme.EXIT_ON_CLOSE);
DatabaseFarme.setResizable(false);
DatabaseFarme.setVisible(true);
// JButton icon details
button.setBorder(BorderFactory.createEmptyBorder());
button.setContentAreaFilled(false);
buttonTwo.setBorder(BorderFactory.createEmptyBorder());
buttonTwo.setContentAreaFilled(false);
buttonThree.setBorder(BorderFactory.createEmptyBorder());
buttonThree.setContentAreaFilled(false);
return DatabaseFarme;
}
}
My second class, it contains the JButton that needs to change panel and close the JDatabaseFarme :
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDatabaseFarme;
import javax.swing.JLabel;
public class SQLsPanel {
JComponent SQLsPanel() throws IOException {
final JComponent SQLsPanel = new JLabel(new ImageIcon(ImageIO.read(new File("res/HowToPlayBG.png"))));
SQLsPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
BufferedImage buttonOneIcon = ImageIO.read(new File("res/Database.png"));
JButton buttonOne = new JButton("",new ImageIcon(buttonOneIcon));
BufferedImage buttonOneIconB = ImageIO.read(new File("res/DatabaseHigh.png"));
buttonOne.setRolloverIcon(new ImageIcon(buttonOneIconB));
buttonOne.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
SQLsPanel.setVisible(false);
try {
Database passme = new Database();
JDatabaseFarme DatabaseFarmeA = passme.mainPanel();
DatabaseFarmeA.add(SQLsPanel);
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
gbc = new GridBagConstraints();
gbc.insets = new Insets(15,15,15,15);
gbc.weighty = 1;
gbc.weightx = 1;
gbc.gridx = 1;
gbc.gridy = 3;
gbc.anchor = GridBagConstraints.PAGE_END;
SQLsPanel.add(buttonOne, gbc);
buttonOne.setBorder(BorderFactory.createEmptyBorder());
buttonOne.setContentAreaFilled(false);
return SQLsPanel;
}
}
Try the following:
final JFrame frame = new JFrame("Lohn Jocke and the Quest for Qualia"); //Had to set frame to final for the action listener
final String name = frame.getName();
Add the variable 'name' just below where you declare the JFrame.
// JFrame settings
frame.add(panel);
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.setSize(860,500);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setVisible(true);
if(Frame.getFrames().length > 1){
Frame[] f = Frame.getFrames();
for(Frame frames : f){
if(!frames.getName().equals(name)){
frames.dispose();
}
}
}
Add this below where you set the JFrame settings.
what happens is when you call this
MainMenu passme = new MainMenu();
From the InstructionsPanel you are creating a new JFrame from your class constructor in addition to the current frame you already have(Hence why you end up with 2). what I have tried to do is get the name of your new Frame you are creating(with the name variable), then using the loop at the bottom wipe all other Frames away leaving you with the new one with which to display your Panel.(Frame.getFrames() returns a list of all frames, I then iterate over removing all the ones that aren't needed)
You may want to tweak it if you add more JFrames in future but hopefully this will be somewhat effective for you for now at least.(i have tried to replicate your code with dummy images to grasp at the problem for this 'fix' so apologies if I have misunderstood the issue here )
Hope this helps.

Setting up a maximum component size when using GridBagLayout in java

My problem is the following : I'm trying to have a JScrollPane resizing with the window, up to a certain size horizontally, where it should stop trying to grow with the window.
Can I do that with a GridBagLayout ? If so, how ?
One way to do that is to wrap you scrollpane in another JPanel with a BoxLayout and set a MaximumSize on your scrollpane which BoxLayout will enforce:
Packed:
Stretched (max width has been set to 700 px):
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.net.MalformedURLException;
import java.util.Arrays;
import java.util.Vector;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
public class TestGridBagLayout2 {
protected void initUI() throws MalformedURLException {
final JFrame frame = new JFrame();
frame.setTitle(TestGridBagLayout2.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel panel = new JPanel(new GridBagLayout());
Vector<Vector<String>> data = new Vector<Vector<String>>();
for (int i = 0; i < 20; i++) {
Vector<String> v = new Vector<String>();
for (int j = 0; j < 1; j++) {
v.add("Cell (" + (i + 1) + "," + (j + 1) + ")");
}
data.add(v);
}
DefaultTableModel model = new DefaultTableModel(data, new Vector<String>(
Arrays.asList("Col-1"/*, "Col-2", "Col-3", "Col-4", "Col-5"*/)));
JTable table = new JTable(model);
JScrollPane scroll = new JScrollPane(table);
scroll.setMaximumSize(new Dimension(700, Integer.MAX_VALUE));
JPanel wrappingPanel = new JPanel(null);
wrappingPanel.setLayout(new BoxLayout(wrappingPanel, BoxLayout.LINE_AXIS));
wrappingPanel.add(scroll);
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.BOTH;
panel.add(wrappingPanel, gbc);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new TestGridBagLayout2().initUI();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
});
}
}

is there a way to set a jbutton on top of a jbutton?

I am wondering about this since we are making a game in Swing and we made our map tiles into jButtons instead of jPanels for whatever reason. Now we want to put units on top of them so the map background is still shown when the unit is on top of them. Anyone know if this is possible?
OK, so I am not sure this is really what you are looking for and how your application is currently set up, but this is an example to have JButtons on top of each other (if this is not what you are looking for, consider posting an SSCCE and give more details). There are other alternatives and better way to handle such thing, but since you asked JButton over a JButton, here is a snippet showing that:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.basic.BasicButtonUI;
public class TestButtonGrid {
protected int x;
protected int y;
protected void initUI() throws MalformedURLException {
final JFrame frame = new JFrame();
frame.setTitle(TestButtonGrid.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel panel = new JPanel(new GridBagLayout());
ImageIcon icon = new ImageIcon(new URL("http://manhack-arcade.net/pivot/isdrawing/tile_bluerock.png"));
ImageIcon unit = new ImageIcon(new URL("http://static.spore.com/static/image/500/642/783/500642783372_lrg.png"));
ButtonUI ui = new BasicButtonUI();
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
gbc.gridx = i;
gbc.gridy = j;
JButton button = new JButton(icon);
button.setBorderPainted(false);
button.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
button.setUI(ui);
button.setOpaque(false);
panel.add(button, gbc);
if (i == j) {
// Choose a layout that will center the icon by default
button.setLayout(new BorderLayout());
JButton player = new JButton(unit);
player.setPreferredSize(new Dimension(unit.getIconWidth(), unit.getIconHeight()));
player.setBorderPainted(false);
player.setUI(ui);
player.setOpaque(false);
button.add(player);
}
}
}
frame.add(panel);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new TestButtonGrid().initUI();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
});
}
}
It might be a better idea to have a panel which contains buttons. Your panel could then use a mouse event listener to perform an action when clicked on.
The advantage of using a jPanel is that you can set a layout within it, which will make positioning your buttons in it much easier.
Well it is possible to put a JButton Over an other JButton you just wont be able to see it.
CardLayout cl = new CardLayout();
JPanel jpnlMain = new JPanel(cl);
jpnlMain.add(new JButton(), "FIRST");
jpnlMain.add(new JButton(), "SECOND");
Then Maybe you could create a Class that Extends Either the Cardlayout or the JPanel to make it show both Items.
EDIT
Made a little Test and HJere is a Button in a Button Buttonception!!
Main class:
import javax.swing.JFrame;
public class Test {
public static void main(String[] arg0){
SpecialButton sp = new SpecialButton();
JFrame jf = new JFrame();
jf.add(sp);
jf.setVisible(true);
jf.pack();
}
}
Special Button Class:
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class SpecialButton extends JButton{
SpecialButton(){
super();
JButton jbtnMid = new JButton();
JLabel jlblMid = new JLabel(new ImageIcon(this.getClass().getResource("/Images/arrowUpIcon.png")));
jbtnMid .add(jlblMid);
this.add(jbtnMid);
this.setVisible(true);
}
}

Categories