Even using the following code the JProgressBar I'm using to display the progress of a download is far from the Windows 10 native look: in other programs the green part of the progress bar fills the entire height of the progress bar but in Java it doesn't seem to be the case. Also when updated the progress bar feels very chunky compared to other programs.
Here's how it looks normally
https://i.imgur.com/xmhWrxf.png
In java
https://i.imgur.com/81T0hbF.png
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
JDialog.setDefaultLookAndFeelDecorated(true);
JFrame.setDefaultLookAndFeelDecorated(true);
the main JFrame of my app
private JButton button = new JButton("Test");
private JProgressBar progressBar = new JProgressBar();
private JPanel panel = new JPanel();
public MainFrame()
{
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
progressBar.setMinimum(0);
progressBar.setMaximum(100);
progressBar.setValue(60);
progressBar.setEnabled(true);
progressBar.setPreferredSize(new Dimension(300, 25));
this.panel.add(progressBar);
this.panel.add(button);
this.setSize(400, 600);
this.setContentPane(panel);
this.setVisible(true);
}
This made my progressbar look much better in my opinion.
public static Font defaultFont = new Font(Font.decode(null).getName(), Font.PLAIN, 12);
progressbar.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
progressbar.setBackground(new Color(230, 230, 230));
progressbar.setForeground(new Color(120, 230, 90));
progressbar.setUI(new BasicProgressBarUI() {
#Override
protected Color getSelectionBackground() {
return new Color(50, 50, 50);
}
#Override
protected Color getSelectionForeground() {
return new Color(50, 50, 50);
}
}
Edit: you can optionally use progressbar.setStringPainted(true) to show the percentage
Related
I'm trying to add two JPanels to a JFrame, one with a simple backround and another one with buttons etc. Either I get only buttons or only the background. I can't find a solution to my problem anywhere, so any help would be appreciated. I'm still new to Java, so please don't hate.
GuiMainMenu:
public class GuiMainMenu extends JFrame implements ActionListener, KeyListener {
private static final long serialVersionUID = -7936366600070922227L;
Color blue = new Color(114, 137, 218);
Color gray = new Color(44, 47, 51);
Color white = new Color(255, 255, 255);
ImagePanel panel = new ImagePanel(new ImageIcon("image.png").getImage());
public static int width;
public static int height;
JPanel p = new JPanel();
JPanel p1 = new JPanel();
JLabel l = new JLabel();
JLabel l1 = new JLabel();
JLabel l2 = new JLabel();
JButton b = new JButton();
JButton b1 = new JButton();
JButton b2 = new JButton();
String title = "-";
public GuiMainMenu() {
setSize(m.X, m.Y);
setTitle(title);
setResizable(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(this);
p.setLayout(null);
width = getWidth();
height = getHeight();
getRootPane().addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
width = getWidth();
height = getHeight();
addButtons();
addLabels();
}
});
addLabels();
addButtons();
add(p);
add(panel);
setVisible(true);
}
public void addLabels() {
l.setSize(width, height);
l.setLocation(5, -40);
l.setText("x");
l.setHorizontalAlignment(SwingConstants.LEFT);
l.setVerticalAlignment(SwingConstants.BOTTOM);
l.setForeground(blue);
l.setFont(new Font("Trebuchet MS", Font.PLAIN, 15));
l1.setSize(width, height);
l1.setLocation(-22, -40);
l1.setText("y");
l1.setHorizontalAlignment(SwingConstants.RIGHT);
l1.setVerticalAlignment(SwingConstants.BOTTOM);
l1.setForeground(blue);
l1.setFont(new Font("Trebuchet MS", Font.PLAIN, 15));
l2.setText("test label");
l2.setSize(width, height);
l2.setLocation(0, -75);
l2.setVerticalAlignment(SwingConstants.CENTER);
l2.setHorizontalAlignment(SwingConstants.CENTER);
l2.setForeground(blue);
l2.setFont(new Font("Trebuchet MS", Font.BOLD, 26));
p.add(l);
p.add(l1);
p.add(l2);
validate();
}
public void addButtons() {
b.setText("button0");
b.setFocusable(false);
b.setBorder(null);
b.setLocation(width / 2 - 200, height / 2 - 35);
b.setSize(400, 35);
b.setForeground(white);
b.setBackground(blue);
b.addActionListener(this);
b1.setText("button1");
b1.setFocusable(false);
b1.setBorder(null);
b1.setLocation(width / 2 - 200, height / 2 + 10);
b1.setSize(400, 35);
b1.setForeground(white);
b1.setBackground(blue);
b1.addActionListener(this);
p.add(b);
p.add(b1);
validate();
}
#Override
public void actionPerformed(ActionEvent arg0) {
}
#Override
public void keyPressed(KeyEvent arg0) {
}
#Override
public void keyReleased(KeyEvent arg0) {
}
#Override
public void keyTyped(KeyEvent arg0) {
}
}
ImagePanel Class:
class ImagePanel extends JPanel {
private static final long serialVersionUID = -7270956677693528549L;
private Image img;
public ImagePanel(String img) {
this(new ImageIcon(img).getImage());
}
public ImagePanel(Image img) {
this.img = img;
}
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, GuiMainMenu.width, GuiMainMenu.height, null);
}
}
p.setLayout(null);
Don't use a null layout. Swing was designed to be used with layout managers.
Read the section from the Swing tutorial on Layout Managers for more information and working examples.
Either I get only buttons or only the background
add(p);
add(panel);
The default layout manager for a JFrame is the BorderLayout. If you don't specify a constraint both components get added to the CENTER. However only the last one added will be displayed.
Try the following to see the difference:
add(p, BorderLayout.PAGE_STRT);
add(panel, BorderLayout.CENTER);
one with a simple backround and another one with buttons etc.
However above is not what you want. Swing components have a parent/child relationship. So what you really need is:
backgroundPanel.add(buttonPanel);
add(backgroundPanel, BorderLayout.CENTER);
Note I used more meaningful names because "p" and "panel" and not descriptive. Use descriptive names for variable so people can understand what they mean.
I suppose you want to display a JFrame with a background image and various components. I think after reviewing your code that there is some misunderstanding on your part causing the problem.
I've created a short snippet of code that does the basics and maybe helps you to solve your problem. (Not tested!)
#SuppressWarnings("serial")
public class GuiMainMenu extends JFrame{
private BufferedImage imageBackground; // TODO: load your background image
public GuiMainMenu(){
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(1024, 768));
setMinimumSize(new Dimension(800, 600));
// TODO: setLayout if needed
JPanel panel = (JPanel)add(new JPanel(){
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(imageBackground, 0, 0, this);
}
});
addOtherComponents(panel);
pack();
setLocationRelativeTo(null);
setTitle("Your Title her");
setVisible(true);
}
private void addOtherComponents(JPanel panel){
//TODO: add the needed Stuff
//panel.add ...
}
}
I'm making a Java Swing app and I came across a problem. I want to make a button with an icon on it.
To make it, I first make a rescaled ImageIcon:
studentIcon = new ImageIcon(new ImageIcon(
"D:\\Programming\\Java\\ELearningDesktop\\src\\com\\core\\student.png")
.getImage().getScaledInstance(64, 64, Image.SCALE_SMOOTH));
Then I make a button and set the icon on it:
JButton studentButton = new JButton();
studentButton.setIcon(studentIcon);
studentButton.setFocusable(false);
It works fine, but for some reason the icon on button becomes pixelated every time I hover mouse onto it. After hovering it never becomes smooth unless I rescale the JFrame, so that it probably calls repaint() somewhere and it repaints it.
I use a downloaded look-and-feel but the problem remains if I use the default look-and-feel. Using ImageIcon the same way, but without rescaling does not help - pixilation still appears.
What could be the solution?
Starting point of the program
public class Starter {
public static void main(String[] args) {
FlatLightLaf.install();
EventQueue.invokeLater(()->{
AuthFrame frame = new AuthFrame();
frame.setVisible(true);
});
}
}
AuthFrame
public class AuthFrame extends JFrame {
private JPanel mainPanel;
private LoginPanel loginPanel;
private ImageIcon studentIcon;
private ImageIcon teacherIcon;
public AuthFrame() {
setLayout(new GridBagLayout());
ImageIcon imageIcon = new ImageIcon(new ImageIcon(
"D:\\Programming\\Java\\ELearningDesktop\\src\\com\\core\\tileBackground.jpg")
.getImage().getScaledInstance(321, 333, Image.SCALE_SMOOTH));
mainPanel = new BackgroundPanel(imageIcon.getImage(), BackgroundPanel.TILED,
0f, 0.5f);
add(mainPanel, new GBC(0, 0).setFill(BOTH).setWeights(1, 1));
mainPanel.setLayout(new GridBagLayout());
studentIcon = new ImageIcon(new ImageIcon(
"D:\\Programming\\Java\\ELearningDesktop\\src\\com\\core\\student.png")
.getImage().getScaledInstance(64, 64, Image.SCALE_SMOOTH));
teacherIcon = new ImageIcon(new ImageIcon(
"D:\\Programming\\Java\\ELearningDesktop\\src\\com\\core\\teacher.png")
.getImage().getScaledInstance(64, 64, Image.SCALE_SMOOTH));
loginPanel = new LoginPanel();
mainPanel.add(loginPanel);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setExtendedState(Frame.MAXIMIZED_BOTH);
}
LoginPanel - a private inner class that is used in the AuthFrame
private class LoginPanel extends JPanel {
private JTextField usernameField;
private JPasswordField passwordField;
private JLabel errorLabel;
private JButton studentButton;
private JButton teacherButton;
private JLabel titleLabel;
private boolean forStudent = true;
public LoginPanel() {
setLayout(new GridBagLayout());
setBackground(new Color(255, 255, 255, 181));
studentButton = new JButton();
studentButton.setIcon(studentIcon);
studentButton.setFocusable(false);
//add(studentButton, new GBC(0, 0).setAnchor(GBC.WEST).setInsets(10));
teacherButton = new JButton(teacherIcon);
teacherButton.setFocusable(false);
add(teacherButton, new GBC(0, 0).setAnchor(GBC.WEST).setInsets(10));
titleLabel = new JLabel("<html>Signing in as <b>student</b></html>");
Utils.deriveFontForTo(titleLabel, 24f);
add(titleLabel, new GBC(1, 0).setAnchor(GBC.EAST).setInsets(10));
titleLabel.setVerticalAlignment(JLabel.BOTTOM);
JLabel usernameLabel = new JLabel("Username");
Utils.deriveFontForTo(usernameLabel, 24f);
add(usernameLabel, new GBC(0, 1).setAnchor(GBC.WEST).setInsets(10));
usernameLabel.setHorizontalAlignment(LEFT);
JLabel passwordLabel = new JLabel("Password");
Utils.deriveFontForTo(passwordLabel, 24f);
add(passwordLabel, new GBC(0, 2).setAnchor(GBC.WEST).setInsets(10));
usernameField = new JTextField(15);
Utils.deriveFontForTo(usernameField, 24f);
add(usernameField, new GBC(1, 1).setInsets(10));
passwordField = new JPasswordField(15);
Utils.deriveFontForTo(passwordField, 24f);
add(passwordField, new GBC(1, 2).setInsets(10));
errorLabel = new JLabel();
Utils.deriveFontForTo(errorLabel, 16f);
errorLabel.setForeground(Color.RED);
add(errorLabel, new GBC(1, 3).setAnchor(GBC.WEST).setInsets(2));
errorLabel.setHorizontalAlignment(LEFT);
JButton loginButton = new JButton("Log in");
loginButton.setFocusable(false);
Utils.deriveFontForTo(loginButton, 24f);
add(loginButton, new GBC(1, 4, 1, 1)
.setFill(GridBagConstraints.HORIZONTAL).setInsets(10));
JButton registerButton = new JButton("Sign Up");
loginButton.setFocusable(false);
Utils.deriveFontForTo(registerButton, 24f);
add(registerButton, new GBC(1, 5, 1, 1)
.setInsets(10));
}
}
GBC - a covenience class to use GridBagLayout
package com.core.helpers.graphics;
import java.awt.*;
public class GBC extends GridBagConstraints {
public GBC(int gridX, int gridY){
super.gridx = gridX;
super.gridy = gridY;
}
public GBC(int gridX, int gridY, int gridWidth, int gridHeight){
super.gridx = gridX;
super.gridy = gridY;
super.gridwidth = gridWidth;
super.gridheight = gridHeight;
}
public GBC setAnchor(int anchor){
super.anchor = anchor;
return this;
}
public GBC setWeights(double weightX, double weightY){
super.weightx = weightX;
super.weighty = weightY;
return this;
}
public GBC setFill(int fill){
super.fill = fill;
return this;
}
public GBC setInsets(int k){
this.insets = new Insets(k,k,k,k);
return this;
}
}
Thanks
Screenshots:
first - two buttons are smooth
second - hovered button becomes pixilated
third - button becomes smooth again after resizing frame
it never becomes smooth unless I rescale the JFrame, so that it probably calls repaint() somewhere and it repaints it.
setBackground(new Color(255, 255, 255, 181));
I would guess the above is related to the problem. Swing does not support transparent backgrounds.
Swing expects the component to be opaque, in which case the component is responsible for painting its opaque background.
Or, the component can be non-opaque in which case the parent component is painted first to make sure an opaque background is painted.
If you have transparency then you need to make the component non-opaque and override the paintComponent method and paint the background yourself.
Basic code is:
JPanel panel = new JPanel()
{
protected void paintComponent(Graphics g)
{
g.setColor( getBackground() );
g.fillRect(0, 0, getWidth(), getHeight());
super.paintComponent(g);
}
};
panel.setOpaque(false); // background of parent will be painted first
panel.setBackground( new Color(255, 0, 0, 20) );
frame.add(panel);
See Backgrounds With Transparency for more information and a reusable solution so you don't need to use custom painting every time.
Edit:
Looks like my problem was connected to windows scaling, as the marked answer here Java Swing, all images appear pixelated
suggests. Using the marked answer from this link helped me. Here it is: https://stackoverflow.com/a/50566705/12538636
Brute force approach :
By repainting the button's panel every time there's a change in button makes it look smooth all the time. Here's code fragment:
teacherButton.getModel().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
mainPanel.repaint();
}
});
studentButton.getModel().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
mainPanel.repaint();
}
});
The only little issue remained is that now there's a tiny gap between hovering and button's respond to hovering (changing a color slightly to denote it's hovered).
So i am trying to make a Menu for a game i am working on.
I want to put an image as background at my menuPanel but i cant figure out how to let the image rescale every time i am raising the window. I have made a JLabel and i have imported an image from my main method and when i launch the game i can see that the image is correctly imported but i want to fill up all menuPanel and also stretch as i am raising the window to full screen or decreasing to the Minimum size of my frame.
How can i do that?
As you can see at the screenshot i want the text to be on top of the image and the image as a background and full screen.
public class Window extends Canvas{
private static final long serialVersionUID = 6331412385749386309L;
private static final int WIDTH = 1024, HEIGHT = WIDTH / 16 * 9;
private JFrame frame;
private JPanel mainPanel;
private JPanel menuPanel;
private JPanel buttonsPanel;
private JPanel playPanel;
private JPanel optionsPanel;
private JButton playBtn;
private JButton optionsBtn;
private JButton quitBtn;
private int currWidth = WIDTH, currHeight = HEIGHT;
public Window(String title, Game game) {
frame = new JFrame(title);
frame.setSize(1024, 576);
frame.setMinimumSize(new Dimension(WIDTH, HEIGHT));
frame.requestFocus();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
menu();
game.start();
}
private void menu() {
frame.getContentPane().setLayout(new BorderLayout(0, 0));
mainPanel = new JPanel();
mainPanel.setBackground(new Color(255, 255, 255));
frame.getContentPane().add(mainPanel);
mainPanel.setLayout(new CardLayout(0, 0));
// menuPanel config
menuPanel = new JPanel();
menuPanel.setForeground(new Color(0, 0, 0));
menuPanel.setBackground(new Color(0, 0, 0));
mainPanel.add(menuPanel, "menuPanel");
buttonsPanel = new JPanel();
buttonsPanel.setBorder(null);
buttonsPanel.setBackground(new Color(0, 0, 0));
// playBtn config
playBtn = new JButton("Play");
playBtn.setForeground(new Color(255, 255, 255));
playBtn.setFont(new Font("Segoe Script", Font.BOLD, 40));
playBtn.setOpaque(false);
playBtn.setContentAreaFilled(false);
playBtn.setBorderPainted(false);
playBtn.setFocusPainted(false);
// optionsBtn config
optionsBtn = new JButton("Options");
optionsBtn.setForeground(new Color(255, 255, 255));
optionsBtn.setFont(new Font("Segoe Script", Font.BOLD, 35));
optionsBtn.setOpaque(false);
optionsBtn.setContentAreaFilled(false);
optionsBtn.setBorderPainted(false);
optionsBtn.setFocusPainted(false);
//quitBtn config
quitBtn = new JButton("Quit");
quitBtn.setForeground(new Color(255, 255, 255));
quitBtn.setFont(new Font("Segoe Script", Font.BOLD, 35));
quitBtn.setOpaque(false);
quitBtn.setContentAreaFilled(false);
quitBtn.setBorderPainted(false);
quitBtn.setFocusPainted(false);
GroupLayout gl_buttonsPanel = new GroupLayout(buttonsPanel);
gl_buttonsPanel.setHorizontalGroup(
gl_buttonsPanel.createParallelGroup(Alignment.TRAILING)
.addGroup(gl_buttonsPanel.createSequentialGroup()
.addContainerGap()
.addGroup(gl_buttonsPanel.createParallelGroup(Alignment.LEADING)
.addComponent(quitBtn, GroupLayout.DEFAULT_SIZE, 175, Short.MAX_VALUE)
.addComponent(playBtn, GroupLayout.DEFAULT_SIZE, 175, Short.MAX_VALUE)
.addComponent(optionsBtn, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
gl_buttonsPanel.setVerticalGroup(
gl_buttonsPanel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_buttonsPanel.createSequentialGroup()
.addContainerGap()
.addComponent(playBtn)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(optionsBtn, GroupLayout.PREFERRED_SIZE, 74, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(quitBtn, GroupLayout.PREFERRED_SIZE, 71, GroupLayout.PREFERRED_SIZE)
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
buttonsPanel.setLayout(gl_buttonsPanel);
//
JLabel menuImageLabel = new JLabel(new ImageIcon(Game.menu_image.getScaledInstance(700, 400, Image.SCALE_FAST)));
//
GroupLayout gl_menuPanel = new GroupLayout(menuPanel);
gl_menuPanel.setHorizontalGroup(
gl_menuPanel.createParallelGroup(Alignment.TRAILING)
.addGroup(gl_menuPanel.createSequentialGroup()
.addComponent(menuImageLabel, GroupLayout.PREFERRED_SIZE, 762, GroupLayout.PREFERRED_SIZE)
.addGap(0)
.addComponent(buttonsPanel, GroupLayout.DEFAULT_SIZE, 195, Short.MAX_VALUE))
);
gl_menuPanel.setVerticalGroup(
gl_menuPanel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_menuPanel.createSequentialGroup()
.addGap(161)
.addComponent(buttonsPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(124))
.addComponent(menuImageLabel, GroupLayout.DEFAULT_SIZE, 537, Short.MAX_VALUE)
);
menuPanel.setLayout(gl_menuPanel);
// playPanel config
playPanel = new JPanel();
playPanel.setBackground(new Color(0, 0, 255));
mainPanel.add(playPanel, "playPanel");
// optionsPanel config
optionsPanel = new JPanel();
optionsPanel.setBackground(new Color(255, 0, 0));
mainPanel.add(optionsPanel, "optionsPanel");
frame.setVisible(true);
setActions();
}
private void setActions() {
// playBtn action
playBtn.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
playBtn.setForeground(new Color(200, 210, 10));
}
public void mouseExited(MouseEvent e) {
playBtn.setForeground(new Color(255, 255, 255));
}
public void mouseClicked(MouseEvent e) {
menuPanel.setVisible(false);
playPanel.setVisible(true);
optionsPanel.setVisible(false);
}
});
// optionsBtn action
optionsBtn.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
optionsBtn.setForeground(new Color(200, 210, 10));
}
public void mouseExited(MouseEvent e) {
optionsBtn.setForeground(new Color(255, 255, 255));
}
public void mouseClicked(MouseEvent e) {
menuPanel.setVisible(false);
playPanel.setVisible(false);
optionsPanel.setVisible(true);
}
});
// quitBtn action
quitBtn.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
quitBtn.setForeground(new Color(200, 210, 10));
}
public void mouseExited(MouseEvent e) {
quitBtn.setForeground(new Color(255, 255, 255));
}
public void mouseClicked(MouseEvent e) {
System.exit(0);
}
});
}
public void tick() {
mainPanel.getSize(new Dimension(currWidth, currHeight));
System.out.println(currWidth + ", " + currHeight);
}
public void render() {
}
}
Swing is based on parent/child relationships.
So if you want the button displayed on the background the structure of your code needs to be:
- frame
- background component
- buttons panel
The easiest way to do this is to use a JLabel with your image as the background. Then you add the buttons panel to the label. The only issue is that by default a JLabel doesn't use a layout manager so you need to see the layout manager to achieve your desired effect.
I would suggest using a GridBagLayout, then the buttons will be centered on the panel. The basic code would be:
JPanel buttons = new JPanel();
buttons.add(...);
JLabel background = new JLabel(...);
background.setLayout( new GridBagLayout() );
background.add(buttons, new GridBagConstraints());
The label will be displayed at the size of the background image.
If you want the background image to scale as the frame size changes, then you have a couple of options:
Use the Stretch Icon. It will automatically scale the image to the space available.
Replace the JLabel with a JPanel and paint the image yourself. Check out the Background Panel which can be configured to automatically scale an image.
Edit:
i tried reading the code and its really confusing.
Well, the intent was not for you to read the code. The intent was for you to use the code.
When you program you learn how to use classes and the methods of the class. When you use the ImageIcon class did you read the code first or just learn how to use its contructor?
Now I agree, the two classes don't have a published API but you really only need to understand the constructors and methods of the classes in order to use them.
If you read the Stretch Icon blog it states:
StretchIcon is a drop-in replacement for ImageIcon, which it extends, except that ImageIcon’s no-arg constructor isn’t supported.
So that means that if you would normally use:
JLabel background = new JLabel( new ImageIcon("background.jpg") );
you would use the following for the StretchIcon:
JLabel background = new JLabel( new StretchIcon("background.jpg") );
Similarly for the BackgroundPanel, if you read the blog it states that it is:
an extension of JPanel that provides some custom painting support for the drawing of images
It then goes on to say that the default is to paint the image "scaled" which is what you want. So all you need to figure out is which constuctor to use to create the panel.
For a regular panel you would use:
JPanel background = new JPanel();
For the BackgroundPanel the simplest constructor to use would be the first constructor of the class which simply takes an Image as a parameter:
JPanel background = new BackgroundPanel(image);
Now you have a panel and you simply add your 3 buttons to the panel.
I did not write the StretchIcon class so I don't know the details of the code, and I don't care about the details as long as the class does what I expect it to do.
I did write the BackgroundPanel class so if you has specific questions then I can probably help you. But I don't have time to guess which part of the code you find confusing.
Edit 2:
I have 3 buttons and i want them to be at the cemter and stretch too so they stay at the center of the image
This is about learning how to use layout managers. I never use an IDE to generate my code. I want full control over the code. This allows your code to be cleaner an more easily maintained.
This allows you to choose the appropriate layout manager for the job and allows you to easily nest panels with different layout mangers. In this case you want to use the GridBagLayout which by default will center horizontally and vertically any component added to it.
By default the BackgroundPanel uses a BorderLayout. But you can easily change it to use the GridBagLayout. Then I would use a second panel with a GridLayout for the buttons.
So the code would be something like:
JPanel buttonPanel = new JPanel( new GridLayout(0, 1, 10, 0) );
buttonPanel.add(playBtn);
...
backgroundPanel.add(buttonPanel, new GridBagConstraints());
Now as the frame size is changed the buttons will automatically re-center.
Read the section from the Swing tutorial on Layout Managers for more information and examples.
Keep a link to the Swing tutorial handy. It contains information and example of most Swing basics.
You could use the method paintComponent(Graphics g) and drawImage() from JPanel to draw your Image.
import java.awt.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class AutoScale extends JFrame{
private Image image;
public AutoScale() {
setTitle("AutoScale");
setResizable(true);
setSize(400,400);
try {
image = ImageIO.read(new File("path to your file"));
}catch(IOException e) {
System.out.println("Image not found");
}
JPanel panelImg = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 30, 30, getWidth()/2, getHeight()/2, null);
}
};
add(panelImg);
}
public static void main(String[] args) {
AutoScale frame = new AutoScale();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
In this example, I create the Panel and paintComponent(). Inside that method, I invoke drawImage() with 6 parameters:
The Image
x Coordinate
y Coordinate
The width of the Frame divided by 2(you can play with the size of your image by adding, substracting or dividing the result of
getWidth())
The height of the Frame divided by 2(same as the width)
The imageObserver, which generally is set to null.
The paintComponent() method gets invoke automatically whenever the size of the Panel changes, so there's no need to use a WindowListener as I suggested earlier.
Note: I use a try-catch block because if it can't find the file, it will throw an Exception.
Hope this was helpful!
I'm currently doing a GUI project as you can see below. While designing the UI I encountered a problem with my JLabel. It wouldn't appear as soon as I run the program.
public class Main extends JFrame {
private JFrame mainFrame;
private JPanel parentPanel;
private JPanel sidePanel;
private JLayeredPane layer;
private JPanel info, tri, sqr, rect, circ;
private JLabel infoTF, triLabel, sqrTF, circTF;
public static void main(String[] args) {
Main show = new Main();
}
public Main() {
mainFrame = new JFrame("Geometric Shapes Computation");
layer = new JLayeredPane();
layer.setLayout(null);
layer.setBounds(0,0,700,600);
Color standard = new Color (76 ,41, 211);
Color fg = new Color (204, 204, 204);
Font items = new Font("Century Gothic", Font.BOLD, 12);
triLabel = new JLabel("Triangle");
triLabel.setFont(items);
triLabel.setBackground(standard);
triLabel.setForeground(fg);
triLabel.setVisible(true);
tri = new JPanel();
tri.add(triLabel);
tri.setBackground(Color.ORANGE);
tri.setLayout(null);
tri.setBounds(0, 215, 200, 70);
sqr = new JPanel();
sqr.setBackground(standard);
sqr.setLayout(null);
sqr.setBounds(0, 315, 200, 70);
parentPanel = new JPanel();
parentPanel.setLayout(null);
parentPanel.setSize(700, 600);
sidePanel = new JPanel();
sidePanel.setLayout(null);
sidePanel.setBounds(0,0,200, 600);
sidePanel.setBackground(standard);
sidePanel.add(tri);
layer.add(parentPanel, JLayeredPane.DEFAULT_LAYER);
layer.add(sidePanel, JLayeredPane.PALETTE_LAYER);
layer.add(tri, JLayeredPane.MODAL_LAYER);
mainFrame.add(layer);
mainFrame.setSize(700, 600);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setResizable(false);
mainFrame.setVisible(true);
}
}
If I am understanding your question correctly you are just having issues displaying the label, I was able to show the label by commenting out the tri.setLayout(null);
tri = new JPanel();
tri.add(triLabel);
tri.setBackground(Color.ORANGE);
//tri.setLayout(null);
tri.setBounds(0, 215, 200, 70);
This was able to display the text for me. Hopefully, this helps.
I am a beginner and I was practicing JRadioButtons. I realised that I can't see my JRadioButtons if I'll not set my layout as 'FlowLayout()'. I want to set the location of the buttons by myself.
I posted my code below, can anyone help me what am I doing wrong?
Thanks!
private JFrame frame;
private JPanel panel;
private JRadioButton btn1, btn2;
public JBButtons() {
form();
radioButtons();
frame.add(panel);
frame.setVisible(true);
}
public void form(){
frame = new JFrame("Frame");
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.setLayout(null);
//panel.setLayout(new FlowLayout());
}
public void radioButtons() {
ButtonGroup group = new ButtonGroup();
btn1 = new JRadioButton("btn1");
btn1.setSelected(true);
btn1.setLocation(50, 50);
btn2 = new JRadioButton("btn2");
btn2.setLocation(50, 70);
group.add(btn1);
group.add(btn2);
panel.add(btn1);
panel.add(btn2);
}
public static void main(String[] args) {
new JBButtons();
}
The issue with absolute positioning or null layout is - it requires you to set the sizes of all your components, otherwise they will stay their default zero-size and won't show up. Better use a layout manager - https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
Add this part of the code when adding the RadioButton to the panel, use the property .setBounds(x, y, width, heigth).
panel.add(btn1);
btn1.setBounds(90, 59, 93, 23);
panel.add(btn2);
btn2.setBounds(180, 60, 93, 23);