JButton default size can't be changed in GridBagLayout - java

JButtons had the default size and I can't change it. I was try with setSize and it don't do anything. When I click on some of JButtons picture will be set and the JButtons will get size of the picture. I want to set size of JButton to be the same like the size of JButton when I click on it(JButton with picture)
btn=new JButton[9];
j=0;
for (i = 0; i <btn.length; i++) {
btn[i] = new JButton("");
btn[i].addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
if(j%2==0){
((JButton) e.getSource()).setIcon(new ImageIcon("resources/X.png"));
}else{
((JButton) e.getSource()).setIcon(new ImageIcon("resources/O.png"));
}
((JButton) e.getSource()).setEnabled(false);
j++;
}
});
}
GridBagConstraints gbc=new GridBagConstraints();
gbc.gridx=0;
gbc.gridy=0;
p2.add(btn[0],gbc);
gbc.gridx=1;
gbc.gridy=0;
p2.add(btn[1],gbc);
gbc.gridx=2;
gbc.gridy=0;
p2.add(btn[2],gbc);
.........

Probably the simplest and most reliable solution is to use a blank image which is the same size as the others as the initial image for the button
Very few layout managers allow you to directly suggest the size of a given component, in fact, the intention is to allow the component to tell the layout manager what it wants and then let the layout manager figure out if it can accomidate it.
For example...
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
BufferedImage img = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setBackground(new Color(255, 255, 255, 0));
g2d.clearRect(0, 0, 32, 32);
g2d.dispose();
GridBagConstraints gbc = new GridBagConstraints();
for (int row = 0; row < 3; row++) {
gbc.gridy = row;
for (int col = 0; col < 3; col++) {
gbc.gridx = col;
add(new JButton(new ImageIcon(img)), gbc);
}
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
In this example I've created my own blank image, you could do the same, but it's just as easy to load blank image, the concept is the same

Related

How can I redraw a grid on a JPanel if the frame gets bigger?

So basically I am trying to code a grid, that adjusts it's size everytime I make the JFrame bigger/smaller.
Now I don't want the grid to take the whole JFrame up, it also is supposed to only grow to a certain extend which I specified with the JPanels MaximumSize, I think.
Here's what I got so far:
public class GridMaker extends JPanel{
public int ROWS = 20; //this is because of 400/40 = 20
public int COLS = 20;
public static int cell_size = 40;
public Cell[][] cells;
public MazePanel(Color c) {
setMinimumSize(new Dimension(400, 400));
setBackground(c);
createCells();
}
//Create content of the array in form of cells
private void createCells() {
cells= new Cell[ROWS][COLS];
Cell cell;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
cell= new Cell(i, j, cell_size, this); //cell class only contains coordinates where to
cells[i][j] = cell; //draw my lines
}
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Cell cell;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
cell = cells[i][j];
if(cell != null) {
cell.draw(g);
}
}
}
repaint();
}
This Grid-Panel I then add onto another panel, called gridShow-Panel which is allowed to have a minimum size of (400, 500) and maximum size of (600, 800). My frame class adds the panel then with a simple gridbaglayout.
Now, I don't know where I can get the width and height of my gridShow-Panel, since only after I add it to my JFrame the measures get finalized, I think. Also I don't know how I can code it so, every time I make my Frame bigger the grid width and height values can get "send" over to my GridMaker class before showing the final grid...
public Frame() {
setTitle("Grid");
setMinimumSize(new Dimension(600, 600));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gridPanel= new GridPanel();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 0.8/1;
add(gridPanel, gbc);
getContentPane().addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
Component c = (Component)e.getSource();
HEIGHT = gridPanel.getHeight(); //Testing if I can get the height and width like this, though when used in ROWS = WIDTH/cell_size nothing works...
WIDTH = gridPanel.getWidth();
System.out.println("Height: "+HEIGHT);
System.out.println("Width: "+WIDTH);
}
});
setResizable(true);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
//Also my GridPanel class:
public class GridPanel extends JPanel{
public GridPanel() {
setMinimumSize(new Dimension(400, 500));
setPreferredSize(new Dimension(600, 800));
setLayout(new GridLayout(1,1));
GridMaker panel = new GridMaker(Color.white);
add(panel);
}
}
Any help would be very much appreciated :)

Can not figure out a simple 4 box JPanel layout

I have been trying for hours to get JPanel in Java to contain these 4 other panels in this configuration (see picture)
The blue box should never change size.
The white box should never change height, can get wider though.
The dark grey box should never change widths, can get taller though.
The light grey box can get taller or wider.
Seems pretty simple to me, I did it in C# the other day and it was a breeze. Set the position, the width, height, and whether a certain side was anchored or not, boom done, I was starting to like java more than C until I ran into this.
I've tried countless combinations of GridBagLayout, multiple nested BoxLayout instances. They all seem to do very strange things, like make each panel a tiny 4 x 4 square, or there is crazy padding around them, or the ones that need to re-size with the window, don't.
Is there some kind of magic combination that can achieve this? Does the null layout do anchoring or percent dimensions.
The closest I've gotten is the bottom image with GridBagLayout, which looks good when it loads, but does that when you re-size the window.
Here is the code that got the above images
class MainPanel extends JPanel {
public MainPanel(){
this.setBackground(new Color(216,216,216));
this.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
JPanel topTitle = new JPanel();
topTitle.setPreferredSize(new Dimension(140, 40));
topTitle.setMinimumSize(new Dimension(140, 40));
topTitle.setBackground(new Color(174, 216, 249));
c.weightx = 0.5;
c.gridx = 0;
c.gridy = 0;
this.add(topTitle,c);
JPanel mainHeader = new JPanel();
mainHeader.setPreferredSize(new Dimension(1060, 40));
mainHeader.setMinimumSize(new Dimension(1060, 40));
mainHeader.setBackground(Color.WHITE);
c.gridx = 1;
c.gridy = 0;
this.add(mainHeader,c);
JPanel sideNav = new JPanel();
sideNav.setPreferredSize(new Dimension(140, 760));
sideNav.setMinimumSize(new Dimension(140, 760));
sideNav.setBackground(new Color(110,110,110));
c.gridx = 0;
c.gridy = 1;
this.add(sideNav,c);
JPanel dataPanel = new JPanel();
dataPanel.setPreferredSize(new Dimension(1060, 760));
dataPanel.setMinimumSize(new Dimension(1060, 760));
dataPanel.setBackground(new Color(216,216,216));
c.gridx = 1;
c.gridy = 1;
this.add(dataPanel,c);
}
}
GUI at minimum size
GUI stretched wider & taller
It's all about getting appropriate resize weights & fill values..
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class FourPanelLayout {
private JComponent ui = null;
FourPanelLayout() {
initUI();
}
public void initUI() {
if (ui!=null) return;
ui = new JPanel(new GridBagLayout());
// It appears you don't want space around the panels.
// If not, commment out or remove this line.
ui.setBorder(new EmptyBorder(4,4,4,4));
// create the panels, each with a transparent image to suggest a size
JPanel bluePanel = new JPanel();
bluePanel.setBackground(Color.CYAN);
bluePanel.add(new JLabel(new ImageIcon(getTransparentImage(40, 20))));
JPanel darkGrayPanel = new JPanel();
darkGrayPanel.setBackground(Color.DARK_GRAY);
darkGrayPanel.add(new JLabel(new ImageIcon(getTransparentImage(40, 20))));
JPanel whitePanel = new JPanel();
whitePanel.setBackground(Color.WHITE);
whitePanel.add(new JLabel(new ImageIcon(getTransparentImage(40, 20))));
JPanel grayPanel = new JPanel();
grayPanel.setBackground(Color.GRAY);
grayPanel.add(new JLabel(new ImageIcon(getTransparentImage(360, 80))));
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 0.0f;
gbc.weighty = 0.0f;
gbc.gridx = 0;
gbc.gridy = 0;
ui.add(bluePanel, gbc);
gbc.weightx = .5f;
gbc.gridx = 1;
ui.add(whitePanel, gbc);
gbc.weighty = .5f;
gbc.gridy = 1;
ui.add(grayPanel, gbc);
gbc.weightx = 0f;
gbc.gridx = 0;
//gbc.gridy
ui.add(darkGrayPanel, gbc);
}
/* We use transparent images to give panels a natural size. */
private Image getTransparentImage(int w, int h) {
return new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
FourPanelLayout o = new FourPanelLayout();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
To implement this, I recommended to use FormLayout.
FormLayout is a powerful, flexible and precise general purpose layout manager. It places components in a grid of columns and rows, allowing specified components to span multiple columns or rows. Not all columns/rows necessarily have the same width/height.
Note: It good to use Windowbuilder in Eclipse or GUI Form in Intellij to automatically place and set the components properties.

Scrollbars disappear when constructing JScrollPane with JPanel

What I want to do is load an image into a JScrollPane, surrounded by other components, and when the window is smaller than the image, it should be surrounded by scrollbars so that you can view the entire image by scrolling around.
I am doing this by constructing a JScrollPane with my own class ImagePanel, which extends JPanel, which paints the image. The image is loaded and displayed correctly, but the scrollbars disappear. Is there some part of JComponents that I've misunderstood or what is wrong?
public class ImagePanel extends JPanel {
private BufferedImage img;
public ImagePanel () {
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, this);
}
public void setImage(BufferedImage img) {
this.img = img;
}
}
public class MainGUI extends JPanel {
private ImagePanel imgP;
private JScrollPane pane;
public MainGUI () {
setLayout(new GridBagLayout());
//Create local components
//JComponents
JButton hideButton = new JButton("Hide");
JButton hidecategoryButton = new JButton ("Hide Category");
JButton removeButton = new JButton("Remove");
JButton searchButton = new JButton("Search");
JButton whatishereButton = new JButton("What is here?");
JComboBox<String> placeComboBox;
JLabel categoriesLabel = new JLabel("Categories");
JLabel newLabel = new JLabel("New: ");
JTextArea categoriesArea = new JTextArea();
JTextField searchField = new JTextField(10);
//Other
String[] placeTypes = {"Named Place", "Described Place"};
//Initialize and add behaviour
searchButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String s = searchField.getText();
}
});
categoriesArea.setEditable(false);
placeComboBox = new JComboBox<>(placeTypes);
searchField.setToolTipText("Search...");
searchField.setMinimumSize(new Dimension(5, 1));
//Just fileloading test
BufferedImage bi2 = null;
try {
bi2 = ImageIO.read(new File("dafoe.jpg"));
}
catch (Exception ex) {
}
imgP = new ImagePanel();
imgP.setImage(bi2);
pane = new JScrollPane(imgP);
//Add to panel
GridBagConstraints gc;
//Top row
JPanel toprowPanel = new JPanel();
toprowPanel.add(newLabel);
toprowPanel.add(placeComboBox);
toprowPanel.add(searchField);
toprowPanel.add(searchButton);
toprowPanel.add(hideButton);
toprowPanel.add(removeButton);
toprowPanel.add(whatishereButton);
gc = new GridBagConstraints();
gc.gridx = 0;
gc.gridy = 0;
gc.weightx = 1;
//gc.gridwidth = 6;
add(toprowPanel, gc);
//Hide category
gc = new GridBagConstraints();
gc.anchor = GridBagConstraints.NORTH;
gc.gridx = 7;
gc.gridy = 3;
gc.weightx = 0;
gc.weighty = 0;
add(hidecategoryButton, gc);
//Category Label
gc = new GridBagConstraints();
gc.anchor = GridBagConstraints.BELOW_BASELINE;
gc.gridx = 7;
gc.gridy = 1;
gc.weightx = 0;
gc.weighty = 0;
add(categoriesLabel, gc);
//categoriesarea
gc = new GridBagConstraints();
gc.anchor = GridBagConstraints.BASELINE_TRAILING;
gc.fill = GridBagConstraints.BOTH;
gc.gridx = 7;
gc.gridy = 2;
gc.ipadx = 5;
gc.ipady = 70;
gc.weightx = 0;
gc.weighty = 0;
add(categoriesArea, gc);
//Image
gc = getImageConstraints();
add(pane, gc);
}
public void updateImage(BufferedImage bi) {
imgP.setImage(bi);
//imgP.repaint();
pane.repaint();
}
private GridBagConstraints getImageConstraints() {
GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.BOTH;
gc.gridheight = 3;
gc.gridwidth = 1;
gc.gridx = 0;
gc.gridy = 1;
gc.weightx = 1;
gc.weighty = 1;
return gc;
}
}
my own class ImagePanel, which extends JPanel, which paints the image. The image is loaded and displayed correctly, but the scrollbars disappear.
The scrollbars will appear automatically when the preferred size of the component added to the scroll pane is greater than the size of the scroll pane.
Your custom component has a preferred size of (0, 0) so the scrollbars will never appear.
You need to override the getPreferredSize() of your ImagePanel class to return the size of the image.
Or even easier just use a JLabel with an ImageIcon and add the label to the scroll pane. A JLabel already implements the getPreferredSize() method correctly.
You can not use the scrollbar when the layout is GridBagLayout. You must use the BorderLayout or FlowLayout
Link example with jtable (similar to the image):
http://myquestionjava.blogspot.com/2016/04/jscrollbars-and-jtable-in-java.html

Do button have a placement in Applet java?

How can I put a button in the right place ?
My code:
import java.applet.*;
import java.awt.*;
public class Banner extends Applet {
int x, y;
Button button1 = new Button("Try!");
public void init() {
setSize(1200, 500);
setLayout(new BorderLayout()); //also I tried FlowLayout..
//button1.setBounds(500, 250, 25, 50); // not worked..
add("East", button1);
button1.addActionListener(this);
}
public void start() {
}
public void paint(Graphics g) {
}
}
For example I have few labels and images in my Applet. And I want put the button somewhere..
And also I want to set size the button, but method setSize() and method setBounds() isn't worked..
Have you tried?
add(button1,BorderLayout.EAST);
you can try GridBagLayout if there are multiple components
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.gridy = 0;
gc.anchor = GridBagConstraints.NORTH;
Image image = ImageIO.read(new File("resources/Tulips.jpg"));
JLabel label = new JLabel(new ImageIcon(image));
JButton button1 = new JButton("Try!");
gc.gridx = 0;
gc.insets = new Insets(5, 5, 5, 5);
add(label, gc);
gc.insets = new Insets(50, 5, 5, 50);
gc.gridx = 1;
add(button1, gc);
You can try it with BorderLayout also by just adding button in new JPanel
Image image = ImageIO.read(new File("resources/Tulips.jpg"));
JLabel label = new JLabel(new ImageIcon(image));
setLayout(new BorderLayout(10,10));
add(label, BorderLayout.CENTER);
JPanel panel=new JPanel(new FlowLayout(FlowLayout.CENTER,50,10));
JButton button1 = new JButton("Try!");
panel.add(button1);
add(panel, BorderLayout.EAST);

JButton only appears after I hover over it?

I was wondering why my button does not show up on the panel until AFTER I hover my mouse over where it would be? It also disappears again if I resize the window. The MainMenuScreen is just an image I use as my background image.
//MainMenu setup
JPanel card2 = new JPanel();
card2.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(2,2,2,2);
gbc.anchor = GridBagConstraints.CENTER;
MainMenuScreen mms = new MainMenuScreen();
mms.setLayout(new FlowLayout());
card2.add(mms);
card2.add(menuButton1, gbc);
Here is how I setup by background image.
public class MainMenuScreen extends JPanel{
private static final long serialVersionUID = 1L;
private BufferedImage background;
public MainMenuScreen() {
try {
background = ImageIO.read(new File("M&M Arcade.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (background != null) {
int x = (getWidth() - background.getWidth());
int y = (getHeight() - background.getHeight());
g.drawImage(background, x, y, this);
}
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(Color.white);
}
}
The JButton doesn't show up beacuse you are using the same GridBagConstraints values for your MainMenuScreen component and your JButton menuButton1, i.e. they exist at the same location. Once the values of gbc are adjusted, the button will appear. Also better to consistently use the correct overloaded method of add when adding to a container with GridBagLayout.
Edit:
There have been numerous discussions on how to implement background images on JPanel containers. A notable one is Background Panel.

Categories