I want to place a JPanel with 300,200 size at 100,50 location in a JFrame, but the following code makes the whole JFrame to be filled with the JPanel, where am I wrong?
Code:
public class Class1 {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.setSize(700, 500);
panel.setSize(300, 200);
panel.setBackground(Color.green);
panel.setCursor(new Cursor(java.awt.Cursor.HAND_CURSOR));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(panel, BorderLayout.CENTER);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
If I change BorderLayout.SOUTH or NORTH, the JPanel looks like a thin line at the bottom or top of the JFrame. Also I tried to use preferred size but its still the same result.
You need to understand the basics of Layout Managers before you can attempt anything with Swing.
Study the tutorial here https://docs.oracle.com/javase/tutorial/uiswing/layout/howLayoutWorks.html
If you are trying to construct a form with various Swing controls, never use absolute coordinates to position them. Resizing the window should dynamically reposition your controls according to the type of layout you want to use. If you are using your panel as a drawing canvas (which is what I think you are after), look at my example below.
Try to master a couple of fundamental layouts first such as BorderLayout and GridLayout. Once mastered you can use very few to achieve just about any kind of layout you desire by nesting them together. Also learn the basics of ScrollPane to make efficient use of screen real-estate
As for your original question, I created an example of how BorderLayout works and how to draw to a specific region on a panel. I also added some code so you can set your cursor differently depending on whether you are in the smaller region within a given panel.
Try this:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class FrameDemo extends JFrame {
private static final long serialVersionUID = 1L;
public FrameDemo() {
super("Frame Demo");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().add(new CustomPanel(Color.RED), BorderLayout.NORTH);
getContentPane().add(new CustomPanel(Color.GREEN), BorderLayout.SOUTH);
getContentPane().add(new CustomPanel(Color.BLUE), BorderLayout.EAST);
getContentPane().add(new CustomPanel(Color.YELLOW), BorderLayout.WEST);
getContentPane().add(new JScrollPane(new CustomPanel(Color.BLACK)), BorderLayout.CENTER);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new FrameDemo();
frame.setVisible(true);
}
});
}
}
class CustomPanel extends JPanel implements MouseMotionListener {
private static final long serialVersionUID = 1L;
private static final Dimension PANEL_SIZE = new Dimension(200, 100);
private static final int HAND_CURSOR_INDEX = 1;
private static final int DEFAULT_CURSOR_INDEX = 0;
private static final Cursor[] _cursors = new Cursor[] {
Cursor.getDefaultCursor(),
Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)
};
// I want to place a JPanel with 300,200 size at 100,50 location in a JFrame
private static final Rectangle _rectangle = new Rectangle(50, 10, 40, 50);
public CustomPanel(Color color) {
setBackground(color);
addMouseMotionListener(this);
}
public Dimension getPreferredSize() {
return PANEL_SIZE;
}
public Dimension getMinimumSize() {
return PANEL_SIZE;
}
public Dimension getMaximumSize() {
return PANEL_SIZE;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(
(int)_rectangle.getX(),
(int)_rectangle.getY(),
(int)_rectangle.getWidth(),
(int)_rectangle.getHeight());
}
#Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent e) {
int cursorIndex = _rectangle.contains(e.getPoint()) ?
HAND_CURSOR_INDEX :
DEFAULT_CURSOR_INDEX;
setCursor(_cursors[cursorIndex]);
}
}
If you want the panel to occupy part of the JFrame (contentpane) you can use other layout managers. He is an example using GroupLayout:
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class Class1 {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.getContentPane().setPreferredSize(new Dimension(700, 500) );
panel.setPreferredSize(new Dimension(300, 200));
panel.setBackground(Color.green);
panel.setCursor(new Cursor(java.awt.Cursor.HAND_CURSOR));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(104)
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 493, GroupLayout.PREFERRED_SIZE)
.addContainerGap(103, Short.MAX_VALUE))
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(100)
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 301, GroupLayout.PREFERRED_SIZE)
.addContainerGap(99, Short.MAX_VALUE))
);
frame.getContentPane().setLayout(groupLayout);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
output:
Another example using BorderLayout with 4 additional "place holder" or feeler panels :
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import java.awt.BorderLayout;
public class Class1 {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout(0, 0));
JPanel centerPanel = new JPanel();
centerPanel.setPreferredSize(new Dimension(300, 200));
centerPanel.setBackground(Color.green);
centerPanel.setCursor(new Cursor(java.awt.Cursor.HAND_CURSOR));
frame.getContentPane().add(centerPanel);
JPanel northPanel = new JPanel();
northPanel.setBackground(Color.RED);
northPanel.setForeground(Color.BLACK);
northPanel.setPreferredSize(new Dimension(0, 150));
frame.getContentPane().add(northPanel, BorderLayout.NORTH);
JPanel westPanel = new JPanel();
westPanel.setBackground(Color.MAGENTA);
westPanel.setPreferredSize(new Dimension(200, 0));
frame.getContentPane().add(westPanel, BorderLayout.WEST);
JPanel southPanel = new JPanel();
southPanel.setBackground(Color.YELLOW);
southPanel.setPreferredSize(new Dimension(0, 150));
frame.getContentPane().add(southPanel, BorderLayout.SOUTH);
JPanel eastPanel = new JPanel();
eastPanel.setBackground(Color.BLUE);
eastPanel.setPreferredSize(new Dimension(200, 0));
frame.getContentPane().add(eastPanel, BorderLayout.EAST);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
output :
import javax.swing.*;
import java.awt.*;
public class Class1 {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JPanel another = new JPanel();
JPanel emptyPanel = new JPanel();
emptyPanel.setPreferredSize(new Dimension(700, 50));
frame.setSize(700, 500);
panel.setMaximumSize(new Dimension(300, 200));
panel.setMinimumSize(new Dimension(300, 200));
panel.setPreferredSize(new Dimension(300, 200));
panel.setBackground(Color.green);
panel.setCursor(new Cursor(java.awt.Cursor.HAND_CURSOR));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
another.add(emptyPanel, BorderLayout.NORTH);
another.add(panel, BorderLayout.CENTER);
frame.add(another);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
The created image looks like below
It looks to me that immediate child container of the JFrame is resized to the size of the JFrame, the top level container, itself.
Related
Please, anyone, tell me how to add the scrollbar to a JTextArea. I tried out many things. but still not able to get it. I copied some codes related to the text area.
public class main extends JPanel {
private JTextArea jcomp1;
public main() {
jcomp1 = new JTextArea(5, 5);
setPreferredSize(new Dimension(944, 574));
// setPreferredSize (new Dimension (1024, 1080));
setLayout(null);
//add components
add(jcomp1);
jcomp1.setBounds(110, 165, 330, 300);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Paraphrasing Tool");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new main());
frame.pack();
frame.setVisible(true);
}
}
Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Netbeans section.
As Andrew said, you have to place the JTextArea inside of a JScrollPane, then place the JScrollPane inside of a JPanel with a Swing layout. I used a BorderLayout.
Here's the GUI after I typed some lines.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class JTextAreaExample extends JPanel {
private static final long serialVersionUID = 1L;
private JTextArea jcomp1;
public JTextAreaExample() {
this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
this.setLayout(new BorderLayout());
jcomp1 = new JTextArea(5, 30);
jcomp1.setMargin(new Insets(5, 5, 5, 5));
JScrollPane scrollPane = new JScrollPane(jcomp1);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
add(scrollPane);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Paraphrasing Tool");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JTextAreaExample(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
}
}
Add the text area to (the viewport of) a JScrollPane. The easiest way is to add it in the constructor. Then add the scroll pane to a panel with a layout (in a GUI that uses layouts).
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 a question on my GUI. after I ran my codes. my GUI will display like the picture shown below
But when I enlarged it to full screen. it will become like this.
How do I keep in the center and just like the size in picture one only when enlarged to full screen?
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class GuiTest {
JFrame frame = new JFrame("Gui Test");
JPanel panel = new JPanel(new GridLayout(4,0));
JPanel panelTwo = new JPanel(new BorderLayout());
JLabel labelOne = new JLabel("Text One:");
JLabel labelTwo = new JLabel("Text Two:");
JTextField textFieldOne = new JTextField(15);
JTextField textFieldTwo = new JTextField(15);
JTextField textFieldThree = new JTextField(15);
public GuiTest() {
panel.add(labelOne);
panel.add(textFieldOne);
panel.add(labelTwo);
panel.add(textFieldTwo);
panelTwo.add(panel, BorderLayout.CENTER);
frame.add(panelTwo);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.getPreferredSize();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//frame.setResizable(false);
}
public static void main(String[]args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new GuiTest();
}
});
}
}
Yet another GridLayout confusion!
It is stretching its children and there is nothing that we can do about it.
GridLayout is a very simple manager with very limited practical
usage. Skip it and skip BorderLayout as well. The only thing that
you need to know about BorderLayout is that it is the default manager
of the frame's content pane.
Layout management is a complex thing -- there not shortcuts. One has to
put some effort to learn it. The good news is that there are some very capable
layout managers. I recommend the following two:
MigLayout
GroupLayout
JGoodies' FormLayout is a good option too. These managers are doing
it properly. Study them carefully and choose your favourite.
I provide two solutions, one with MigLayout, one with GroupLayout.
MigLayout solution
MigLayout is a third-party layout manager for which we need to dowload
a single jar file.
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
public class MigLayoutEx extends JFrame {
public MigLayoutEx() {
initUI();
}
private void initUI() {
JPanel pnl = new JPanel(new MigLayout("ins dialog, center, "
+ "center, wrap"));
pnl.add(new JLabel("Text one"));
pnl.add(new JTextField(15));
pnl.add(new JLabel("Text two"));
pnl.add(new JTextField(15));
add(pnl);
pack();
setTitle("MigLayout example");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MigLayoutEx ex = new MigLayoutEx();
ex.setVisible(true);
}
});
}
}
GroupLayout solution
GroupLayout is a built-in layout manager.
package com.zetcode;
import java.awt.Container;
import java.awt.EventQueue;
import javax.swing.GroupLayout;
import static javax.swing.GroupLayout.Alignment.LEADING;
import static javax.swing.GroupLayout.DEFAULT_SIZE;
import static javax.swing.GroupLayout.PREFERRED_SIZE;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class GroupLayoutEx extends JFrame {
public GroupLayoutEx() {
initUI();
}
private void initUI() {
Container pane = getContentPane();
GroupLayout gl = new GroupLayout(pane);
pane.setLayout(gl);
JLabel lbl1 = new JLabel("Text one");
JLabel lbl2 = new JLabel("Text two");
JTextField field1 = new JTextField(15);
JTextField field2 = new JTextField(15);
gl.setAutoCreateGaps(true);
gl.setAutoCreateContainerGaps(true);
gl.setHorizontalGroup(gl.createSequentialGroup()
.addGap(5, 50, Short.MAX_VALUE)
.addGroup(gl.createParallelGroup(LEADING)
.addComponent(lbl1)
.addComponent(field1, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE)
.addComponent(lbl2)
.addComponent(field2, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE))
.addGap(5, 50, Short.MAX_VALUE)
);
gl.setVerticalGroup(gl.createSequentialGroup()
.addGap(5, 50, Short.MAX_VALUE)
.addGroup(gl.createSequentialGroup()
.addComponent(lbl1)
.addComponent(field1, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE)
.addComponent(lbl2)
.addComponent(field2, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE))
.addGap(5, 50, Short.MAX_VALUE)
);
pack();
setTitle("GroupLayout example");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
GroupLayoutEx ex = new GroupLayoutEx();
ex.setVisible(true);
}
});
}
}
I'm making a small game and at the beginning i want to have JCheckBox for choosing the language(after that they are few more of them for setting the game) and above that a jlabel with picture with name of the game OR draw an image there, the problem is that i dont know any other way how to center the panel with checkboxes then to use GridBagLayout and when i use this, i cannot draw anything to the frame, id like to also remove those grey lines around the checkboxes if its possible, appreciate any help, thanks.
This is my second question here and i cant add images yet so here is a link to the picture :
here is code for the frame
private GamePlan plan;
private JFrame frame;
private String language;
private JPanel panel;
private JCheckBox englishBox;
private JCheckBox germanBox;
public Settings(GamePlan plan){
this.plan = plan;
frame = new JFrame();
frame.setSize(600, 500);
frame.setLocation(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.setResizable(false);
frame.setVisible(true);
panel = new JPanel(new GridLayout(2, 1));
englishBox = new JCheckBox("English", false);
germanBox = new JCheckBox("German", false);
englishBox.addActionListener(new EnglishLanguage());
germanBox.addActionListener(new GermanLanguage());
panel.add(englishBox);
panel.add(germanBox);
englishBox.setOpaque(false);
germanBox.setOpaque(false);
panel.setOpaque(false);
frame.add(panel);
frame.getContentPane().setBackground(new Color(216,252,202));
}
" the problem is that i dont know any other way how to center the panel with checkboxes then to use GridBagLayout and when i use this, i cannot draw anything to the frame"
I can't really tell what you're doing wrong without a complete example. I don't even see where you're trying to add the image. But don't try and draw on the frame. Draw on a JPanel instead.
Here is an example you may be able to gain some insight from.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
public class ImageByDrawing {
public ImageByDrawing() {
ImagePanel imagePanel = new ImagePanel();
imagePanel.setBorder(new TitledBorder("Drawn Image onto JPanel"));
JCheckBox germanBox = new JCheckBox("German");
germanBox.setOpaque(false);
JCheckBox englishBox = new JCheckBox("English");
englishBox.setOpaque(false);
JPanel boxPanel = new JPanel();
boxPanel.setBorder(new TitledBorder("JPanel with default FlowLayout"));
boxPanel.setOpaque(false);
boxPanel.add(germanBox);
boxPanel.add(englishBox);
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.add(imagePanel, BorderLayout.CENTER);
centerPanel.add(boxPanel, BorderLayout.SOUTH);
centerPanel.setBorder(new TitledBorder("JPanel with BorderLayout"));
centerPanel.setOpaque(false);
JPanel mainPanel = new JPanel(new GridBagLayout());
mainPanel.add(centerPanel);
mainPanel.setBorder(new TitledBorder("JPanel with GridBagLayout"));
mainPanel.setBackground(new Color(216,252,202));
JFrame frame = new JFrame();
frame.add(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class ImagePanel extends JPanel {
BufferedImage img;
int dWidth;
int dHeight;
public ImagePanel() {
try {
img = ImageIO.read(getClass().getResource("/resources/stackblack.jpg"));
dWidth = img.getWidth();
dHeight = img.getHeight();
} catch (IOException ex) {
Logger.getLogger(ImageByDrawing.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), this);
}
#Override
public Dimension getPreferredSize() {
return (img == null) ? new Dimension(300, 300) : new Dimension(dWidth, dHeight);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new ImageByDrawing();
}
});
}
}
Also I don't know why you prefer to draw the image. The same can be easily done with a JLabel and ImageIcon
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagLayout;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
public class ImageByDrawing {
public ImageByDrawing() {
ImageIcon icon = new ImageIcon(getClass().getResource("/resources/stackblack.jpg"));
JLabel label = new JLabel(icon);
label.setBorder(new TitledBorder("JLabel with ImageIcon"));
JCheckBox germanBox = new JCheckBox("German");
germanBox.setOpaque(false);
JCheckBox englishBox = new JCheckBox("English");
englishBox.setOpaque(false);
JPanel boxPanel = new JPanel();
boxPanel.setBorder(new TitledBorder("JPanel with default FlowLayout"));
boxPanel.setOpaque(false);
boxPanel.add(germanBox);
boxPanel.add(englishBox);
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.add(label, BorderLayout.CENTER);
centerPanel.add(boxPanel, BorderLayout.SOUTH);
centerPanel.setBorder(new TitledBorder("JPanel with BorderLayout"));
centerPanel.setOpaque(false);
JPanel mainPanel = new JPanel(new GridBagLayout());
mainPanel.add(centerPanel);
mainPanel.setBorder(new TitledBorder("JPanel with GridBagLayout"));
mainPanel.setBackground(new Color(216, 252, 202));
JFrame frame = new JFrame();
frame.add(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ImageByDrawing();
}
});
}
}
The last part of your question, as #Jere pointed out you can use setFocusPainted for the check box germanBox.setFocusPainted(false);
here is piece of my code:
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
JPanel a = new JPanel();
a.setAlignmentX(Component.CENTER_ALIGNMENT);
a.setPreferredSize(new Dimension(100, 100));
a.setBorder(BorderFactory.createTitledBorder("aa"));
JPanel b = new JPanel();
b.setAlignmentX(Component.CENTER_ALIGNMENT);
b.setPreferredSize(new Dimension(50, 50));
b.setBorder(BorderFactory.createTitledBorder("bb"));
pane.add(a);
pane.add(b);
problem is with the width of second panel as you can see in image:
How can I fix it ?
because in flow layout it looks like I want:
As mentioned before, BoxLayout pays attention to a component's
requested minimum, preferred, and maximum sizes. While you are
fine-tuning the layout, you might need to adjust these sizes.¹
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class BoxLayoutDemo {
private static void createAndShowGUI(){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
JPanel a = new JPanel();
a.setAlignmentX(Component.CENTER_ALIGNMENT);
a.setPreferredSize(new Dimension(100, 100));
a.setMaximumSize(new Dimension(100, 100)); // set max = pref
a.setBorder(BorderFactory.createTitledBorder("aa"));
JPanel b = new JPanel();
b.setAlignmentX(Component.CENTER_ALIGNMENT);
b.setPreferredSize(new Dimension(50, 50));
b.setMaximumSize(new Dimension(50, 50)); // set max = pref
b.setBorder(BorderFactory.createTitledBorder("bb"));
frame.getContentPane().add(a);
frame.getContentPane().add(b);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
createAndShowGUI();
}
});
}
}
¹ How to Use BoxLayout: Specifying Component Sizes .