JPanel shrinks when I click on button - java

Whenever I click my show password button the panels shrink and become as in the pictures my code is below:
public class AssetLogin extends JFrame implements ActionListener, MouseListener {
private static final long serialVersionUID = 1L;
private JPanel layout, panLogin, panEmail, panPassword;
private JButton btnShowPassword;
private JTextField txtEmail;
private JPasswordField txtPassword;
public AssetLogin() {
super("Asset And Equipment Tracking");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setExtendedState(Frame.MAXIMIZED_BOTH);
this.setLocationRelativeTo(null);
this.pack();
this.setVisible(true);
this.setResizable(false);
this.setMinimumSize(new Dimension(750, 500));
JFrame.setDefaultLookAndFeelDecorated(false);
getContentPane().setLayout(new BorderLayout(0, 0));
UIManager.put("TextField.border", BorderFactory.createMatteBorder(0, 0, 0, 0, Color.WHITE));
UIManager.put("PasswordField.border", BorderFactory.createMatteBorder(0, 0, 0, 0, Color.WHITE));
UIManager.put("Button.background", Color.WHITE);
UIManager.put("Button.foreground", Color.GRAY);
UIManager.put("Button.border", BorderFactory.createMatteBorder(0, 0, 0, 0, Color.WHITE));
UIManager.put("Button.focus", new Color(0,0,0,0));
UIManager.put("Button.select", new Color(0, 0, 0, 0));
layout = new JPanel();
layout.setLayout(null);
layout.setSize(this.getWidth(), this.getHeight());
layout.setBackground(Color.WHITE);
initialize();
getContentPane().add(layout);
}
private void initialize() {
panEmail = new JPanel();
panPassword = new JPanel();
txtEmail = new JTextField();
txtPassword = new JPasswordField();
setBoundsResize();
setDecorations();
btnShowPassword.addActionListener(this);
btnShowPassword.addMouseListener(this);
panLogin.add(panEmail);
panLogin.add(panPassword);
panEmail.add(txtEmail);
panPassword.add(txtPassword);
panPassword.add(btnShowPassword);
layout.add(panLogin);
}
private void setBoundsResize () {
panLogin.setBounds(layout.getWidth() / 2 - layout.getWidth() / 4, layout.getHeight() / 2 - layout.getHeight() / 3, layout.getWidth() / 2, (2 * layout.getHeight()) / 3);
panEmail.setBounds(10, 10, panLogin.getWidth() - 10, 60);
panPassword.setBounds(10, 100, panLogin.getWidth() - 10, 60);
btnShowPassword.setBounds(panPassword.getWidth() - 120, 15, 100, panPassword.getHeight() - 25);
txtEmail.setBounds(10, 15, panEmail.getWidth() - 20, panEmail.getHeight() - 25);
txtPassword.setBounds(10, 15, panPassword.getWidth() - 130, panPassword.getHeight() - 25);
}
private void setDecorations() {
layout.setBackground(Color.WHITE);
layout.setBorder(BorderFactory.createMatteBorder(0, 2, 2, 2, Color.LIGHT_GRAY));
panLogin.setOpaque(false);
panEmail.setOpaque(false);
panPassword.setOpaque(false);
panEmail.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), "Email"));
panPassword.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), "Password"));
btnShowPassword.setOpaque(false);
txtPassword.setEchoChar('*');
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnShowPassword) {
if (txtPassword.getEchoChar() == '*') {
txtPassword.setEchoChar( (char) 0 );
//btnShowPassword.setOpaque(true);
btnShowPassword.setBorder(
BorderFactory.createLineBorder(Color.black));
} else {
txtPassword.setEchoChar( '*' );
//btnShowPassword.setOpaque(false);
btnShowPassword.setBorder(null);
}
}
}
#Override
public void mousePressed(MouseEvent e) {
btnShowPassword.setBackground(null);
}
#Override
public void mouseReleased(MouseEvent e) {
btnShowPassword.setBackground(Color.LIGHT_GRAY);
}
}
of course i added the rest of the mouse event methods but the thing is that as i said the JPanels shrinks when i click "show password" button here how it should look like:
how it look like when I click the button:
Why is this happening?

Try getting rid of:
this.pack();
The Window.pack() method causes your frame to resize which will cause all your child elements to resize to their preferred sizes:
Causes this Window to be sized to fit the preferred size and layouts of its subcomponents. The resulting width and height of the window are automatically enlarged if either of dimensions is less than the minimum size as specified by the previous call to the setMinimumSize method.
If the window and/or its owner are not displayable yet, both of them are made displayable before calculating the preferred size. The Window is validated after its size is being calculated.
If you're not setting your preferred sizes correctly this can cause the types of distortion you're seeing.

Don't forget to add the layout for each panel since this will cause that problem when you are putting:
this.pack();
Since the Window.pack() method causes your frame to resize which will cause all your child elements to resize to their preferred sizes:
Causes this Window to be sized to fit the preferred size and layouts of its subcomponents. The resulting width and height of the window are automatically enlarged if either of dimensions is less than the minimum size as specified by the previous call to the setMinimumSize method.
If the window and/or its owner are not displayable yet, both of them are made displayable before calculating the preferred size. The Window is validated after its size is being calculated.
If you're not setting your preferred sizes correctly this can cause the types of distortion you're seeing.

Related

JLabels not showing in JPanel if bounds not set

I have the following code:
public JPanel getPanel() {
if(jpanel == null) {
jpanel = new JPanel();
jpanel.setLayout(new FlowLayout());
jpanel.setBounds(x, y, width, height);
jpanel.setBackground(Color.WHITE);
JLabel tituloLbl = new JLabel(titulo);
JLabel cantidadLbl = new JLabel(""+cantidad);
JLabel abejasLbl = new JLabel("Abejas");
//tituloLbl.setBounds(0, 0, 50, 15);
jpanel.add(tituloLbl);
jpanel.add(cantidadLbl);
jpanel.add(abejasLbl);
}
return jpanel;
}
The panel should look like a small white box with 3 labels in it, however, the labels don't show unless I set their bounds. Why does this happen? If I'm setting a FlowLayout, the labels should be positioned automatically.
This is how the panel shows:
Solved it, I had to call panel.validate() on my main frame in order to show them.

Java setResizable issue

package data;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main extends JFrame implements Runnable {
private JPanel contentPane;
private JPanel pp = new JPanel();
Thread page = new Thread();
public void run() {
while (!Thread.interrupted()) {
}
}
public Main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 640 + 16, 480 + 39);
contentPane = new JPanel();
contentPane.setBounds(0, 0, 640, 480);
contentPane.setLayout(null);
setContentPane(contentPane);
pp.setBounds(0, 0, 640, 480);
pp.setBackground(Color.BLACK);
contentPane.add(pp);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
frame.setResizable(false);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
The above code works but setResizable causes an issue: http://i.stack.imgur.com/hQxPU.png
If I were to remove the setResizable then the grey at the bottom and right would be black like it's meant to. How can I disable resizing without causing this issue?
You're using an absolute layout (no LayoutManager set), and the black panel has fixed bounds. And that's exactly the reason the black panel won't fill its parent's bounds when the parent is resized.
Solution: use a LayoutManager which automatically recalculates the bounds of your content so it fills the available space.
// BorderLayout is your friend
contentPane.setLayout(new BorderLayout());
...
// delete this line, no need to set fixed bounds
// pp.setBounds(0, 0, 640, 480);
More on how to use layout managers in AWT/Swing:
The Java™ Tutorials - Using Layout Managers
Layout Managers have two purposes:
calculate the min/max/preferred size of a container
layout components by setting their bounds within the container.
If you want the black panel to have a size of 640x480, and the window to be non-resizable, you can set the preferred size and then pack the window, causing its size to become appropriate for the content's preferred dimensions:
pp.setPreferredSize(new Dimension(640, 480));
...
pack();

jbutton refuses to change transparency

I currently have a function which sets the background and have 1 button. The button is a PNG file and is transparent, I have done all the setOpaque stuff but the button still have a white background behind it. If anyone could help will be greatly appreciated! :)
I have attached my function below:
public JPanel createContentPane() throws IOException{
//Full back pane
JPanel fullGUI = new JPanel();
fullGUI.setLayout(null);
//background pane
JPanel backgroundPane = new JPanel() {
BufferedImage image = ImageIO.read(new File("UI/back2.jpg"));
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, 1200, 750, this);
}
};
backgroundPane.setLayout(null);
backgroundPane.setLocation(0,0);
backgroundPane.setSize(1200,750);
fullGUI.add(backgroundPane);
//button pane
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(null);
buttonPanel.setLocation(0, 250);
buttonPanel.setSize(1200, 500);
fullGUI.add(buttonPanel);
JButton playButton = new JButton(new ImageIcon(("UI/play.png")));
playButton.setLocation(399,47);
playButton.setSize(405,308);
playButton.setOpaque(false);
playButton.setContentAreaFilled(false);
playButton.setBorderPainted(false);
playButton.setFocusPainted(false);
buttonPanel.add(playButton);
fullGUI.setOpaque(true);
return fullGUI;
}
Have you tried setting the color to transparent?
try this:
playButton.setBackground(new Color(0.0f, 0.0f, 0.0f, 0.3f);
This sets the R to 0, G to 0, B to 0, and alpha(transparency) to 0.3.
Make sure to use float values to set the colours. the numbers can be tweaked to whatever you like. If you want to change the transparency, change the last number to higher for more opaque, and lower for less.
Good Luck!

Gradient background in a JFrame

I have googled this and read a lot but did not find an answer that suits my needs, so I'll ask here:
I would like to have a gradient background in my JFrame. Currently the background is a single colour. My code looks something like this:
//imports
public class Game {
//some other irrelevant instance variables
JFrame frame = new JFrame("Game");
public Game() {
frame.getContentPane().setBackground(new Color(200,220,200));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setPreferredSize(new Dimension(frameX,frameY)); //frameX and frameY are instance variables
getMenu(); //method that adds a few JLabels to the JFrame and so on
}
}
The methods that I have read about apply to classes that extend JPanel or JFrame (and then use GradientPaint or something like that), but as you can see I use JFrame as an instance variable. Can someone help me out?
Edit: Picture:
Now, obviously, your example image above does not specify buttons and does not add a label for the message at the bottom. But since it was obvious you intended the user to select those options, I used buttons. The label at the bottom is just to show proof they are buttons (with an action listener attached, to show the message).
The advantage of using actual buttons is that they are also keyboard accessible (press Enter to see the first message, press Tab to navigate to the next one...
If the game does not need to be keyboard accessible, you can swap those out for labels and add a mouse listener. I'll leave that to you.
The code has a lot of comments containing the word 'adjust'. Look at them closely, check the JavaDocs, adjust them as needed..
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class GradientPaintBackground {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
// the GUI as seen by the user (without frame)
JPanel gui = new JPanel(new BorderLayout(15, 15)) {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Point point1 = new Point(10, 10);
Point point2 = new Point(
getWidth() - 10,
getHeight() - 10);
final GradientPaint gp = new GradientPaint(
point1, Color.YELLOW,
point2, new Color(255, 225, 100),
true);
// we need a Graphics2D to use GradientPaint.
// If this is Swing, it should be one..
final Graphics2D g2 = (Graphics2D) g;
g2.setPaint(gp);
g.fillRect(0, 0, getWidth(), getHeight());
}
};
// adjust size to need.
gui.setBorder(new EmptyBorder(20, 20, 20, 20));
// Start: Add components
// adjust size to size of logo
BufferedImage logo = new BufferedImage(
100, 40, BufferedImage.TYPE_INT_RGB);
JLabel logoLabel = new JLabel(new ImageIcon(logo));
gui.add(logoLabel, BorderLayout.NORTH);
// adjust spacing to need
JPanel menuPanel = new JPanel(new GridLayout(0, 1, 20, 20));
menuPanel.setBorder(new EmptyBorder(5, 55, 5, 5));
// allow the BG to show through..
menuPanel.setOpaque(false);
gui.add(menuPanel);
String[] actionTexts = new String[]{
"Play Game", "Tutorial", "Other"
};
final JLabel messages = new JLabel("Ready to play? "
+ "Select an option");
gui.add( messages, BorderLayout.PAGE_END );
ActionListener al = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof JButton) {
JButton b = (JButton)e.getSource();
messages.setText(b.getText() + " selected!");
}
}
};
for (int ii = 0; ii < actionTexts.length; ii++) {
JButton b = new JButton(actionTexts[ii]);
b.setContentAreaFilled(false);
b.setHorizontalAlignment(SwingConstants.LEADING);
b.setBorder(null);
b.addActionListener(al);
menuPanel.add(b);
}
// End: Add components
JFrame f = new JFrame("Gradient Background in JFrame");
f.add(gui);
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See https://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
f.setMinimumSize(f.getSize());
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency
SwingUtilities.invokeLater(r);
}
}
General Tip
Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. This is why you are continually seeing the types of problems you see. Toss layouts out the window, and all hell breaks loose.
To organize the components for a robust GUI, instead use layout managers, or combinations of them1, along with layout padding & borders for white space2.

Improper Alignment Error with Java AWT. Cannot get my label to move

I have put a label into my frame, but it refuses to move. SetBounds() is not working, and I get an improper alignment error if I put any argument past "Result" below that isn't 0, 1, or 2, none of which put it in the correct place. Here's where I declare the Label:
Label result = new Label("Result.", 3);
Here's the SetBounds statement:
result.setBounds(0, 1500, 100, 20);
This program I am writing, I simply just want to have the user input 2 numbers, add them, and print the result using GUI components. The result is the label which refuses to change. The code of the entire program is below, and the program is still not done yet, but if you compile it, result is always stuck to the left and I want it to be at the same level as the TextFields. This problem is actually happening with the other labels, Help1, and Help2. Please don't tell me I have to use swing! I dislike swing.
I have yet to change the event to where it adds the user inputs. I copied the event from a previous program.
The code: (Sorry for no comments, but it's not a huge program)
import java.awt.*;
import java.awt.event.*;
public class MouseClick {
TextField number1;
TextField number2;
public static void main(String[] args) {
MouseClick MC = new MouseClick();
}
public MouseClick() {
Frame f = new Frame("Addition Time!");
Button button = new Button("Click Here To Add The Two Numbers.");
button.setBounds(175, 250, 230, 30);
button.addMouseListener(new MyMouseListener());
f.add(button);
Label help1 = new Label("Enter the first number below.");
Label help2 = new Label("Enter the second number below.");
Label exprsn1 = new Label("+", 0);
Label exprsn2 = new Label("=", 0);
Label result = new Label("Result.", 3);
number1 = new TextField("TextField1", 100);
number2 = new TextField("TextField2", 100);
help1.setBounds(50, 80, 150, 20);
help2.setBounds(250, 80, 150, 20);
exprsn1.setBounds(00, 80, 30, 30);
exprsn2.setBounds(00, 80, 30, 30);
number1.setBounds(50, 100, 100, 20);
number2.setBounds(250, 100, 100, 20);
result.setBounds(0, 1500, 100, 20);
f.add(number1);
f.add(number2);
f.add(help1);
f.add(help2);
f.add(result);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
f.setSize(600, 300);
f.setVisible(true);
}
public class MyMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent me) {
String S = number1.getText();
number2.setText(S);
}
}
}
The error is because 3 is not an allowed value for parameter "alignment" in the constructor
Label(String text, int alignment)
Are you getting confused with TextField() which has a similar constructor?
TextField(String text, int columns)
The reason the label is not appearing in the correct location is because you've not specified your using null layout explicitly. You need this line:
public MouseClick() {
Frame f = new Frame("Addition Time!");
f.setLayout(null); // add this line

Categories