Related
I've been working on a login screen for a new project and came across a weird rendering "error" while using CardLayout on windows.
SignUp screen on Mac:SignUp Screen Mac
The screens load up correctly on my Mac computer, but on windows they look like these after you click "Register" or after you click "Back".
The same screens on windows:SignUp Screen Windows
As you can see, on windows the SignUp "card" from the CardLayout is rendered over the Login "card" without hiding the other one and vise versa, not like on mac.
Now my question is, could this be caused because of the transparent background and therefore windows thinks that the one behind should still be visible, or could it be creating a brand new "card" each time i switch, or just be forgetting to hide the one in the back all together?
Why does this work on Mac but not on Windows?
And also, how could i go about fixing this?
I will put the whole Class so you can test it for yourself.
(Side note: you may also notice that the button "Register" shows the white button shape on windows even though it has btnRegister.setBorder(null); set (works on Mac))
The complete one Class code:
package testing;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import utilities.ComponentMover;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
import javax.swing.JSeparator;
import javax.swing.JPasswordField;
#SuppressWarnings("serial")
public class ClientStarter extends JFrame implements ActionListener {
JPanel cards;
private int height = 450;
private int width = 700;
private int trasparancy = 90;
private int labelWidth = 400;
final static String BACK = "Back";
final static String REGISTER = "Register";
private Color textLine = Color.GRAY;
private Color textColor = Color.WHITE;
private Color tipColor = Color.GRAY;
private Color disabledTipColor = new Color(90, 90, 90);
// LOGIN //
JPanel loginCard;
public static JTextField usernameIn = new JTextField();
private JLabel userLabel = new JLabel("Username :");
public static JPasswordField passwordIn = new JPasswordField();
private JLabel passLabel = new JLabel("Password :");
private JButton btnLogin = new JButton("Login");
private JButton btnRegister = new JButton(REGISTER);
private JLabel registerLabel = new JLabel("Don't own an Account? ");
private JSeparator separatorUser = new JSeparator();
private JSeparator separatorPass = new JSeparator();
// SIGNUP //
JPanel joinCard;
public static JTextField emailNew = new JTextField();
public static JLabel newEmailLabel = new JLabel("Email : (Not Available)");
public static JTextField usernameNew = new JTextField();
public static JLabel newUserLabel = new JLabel("Username :");
public static JTextField passwordNew = new JTextField();
public static JLabel newPassLabel = new JLabel("Password :");
public static JTextField passwordNew2 = new JTextField();
public static JLabel newPassLabel2 = new JLabel("Re-enter password :");
private JButton btnSignUp = new JButton("Signup");
private JButton btnBack = new JButton(BACK);
private JSeparator separatorMailNew = new JSeparator();
private JSeparator separatorUserNew = new JSeparator();
private JSeparator separatorPassNew = new JSeparator();
private JSeparator separatorPassNew2 = new JSeparator();
public ClientStarter() {
getContentPane().setBackground(Color.GRAY);
setUndecorated(true);
setBackground(new Color(0, 0, 0, trasparancy));
setTitle("EnChant");
setSize(width, height);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
setResizable(false);
//Create the cards
// LOGIN //
Font avenir = new Font("Avenir", Font.PLAIN, 18);
loginCard = new JPanel();
loginCard.setLayout(null);
usernameIn.setBounds(348, 150, 327, 35);
usernameIn.setColumns(10);
usernameIn.setFont(avenir);
usernameIn.setBorder(null);
passwordIn.setBounds(348, usernameIn.getY() + 74, 327, 35);
passwordIn.setColumns(10);
passwordIn.setFont(avenir);
passwordIn.setBorder(null);
userLabel.setBounds(usernameIn.getX(), usernameIn.getY() - 20, labelWidth, 16);
userLabel.setFont(avenir);
passLabel.setBounds(passwordIn.getX(), passwordIn.getY() - 20, labelWidth, 16);
passLabel.setFont(avenir);
btnLogin.setBounds(348, passwordIn.getY() + 81, 327, 45);
btnLogin.addActionListener(this);
registerLabel.setBounds(btnLogin.getX(), btnLogin.getY() + btnLogin.getHeight() + 5, labelWidth, 16);
registerLabel.setFont(new Font("Avenir", Font.PLAIN, 13));
btnRegister.setBounds(btnLogin.getX() + 130, registerLabel.getY() - 1, 70, 16);
btnRegister.addActionListener(this);
btnRegister.setBorder(null);
loginCard.setBackground(new Color(0, 0, 0, trasparancy));
usernameIn.setBackground(new Color(0, 0, 0, 0));
usernameIn.setForeground(textColor);
passwordIn.setBackground(new Color(0, 0, 0, 0));
passwordIn.setForeground(textColor);
userLabel.setForeground(tipColor);
passLabel.setForeground(tipColor);
btnLogin.setForeground(new Color(70, 130, 180));
btnLogin.setBackground(Color.WHITE);
btnRegister.setForeground(new Color(70, 130, 180));
registerLabel.setForeground(tipColor);
separatorUser.setForeground(textLine);
separatorUser.setBounds(usernameIn.getX(), usernameIn.getY()+usernameIn.getHeight()-8, usernameIn.getWidth(), 6);
separatorPass.setForeground(textLine);
separatorPass.setBounds(passwordIn.getX(), passwordIn.getY()+passwordIn.getHeight()-8, passwordIn.getWidth(), 6);
loginCard.add(usernameIn);
loginCard.add(separatorUser);
loginCard.add(userLabel);
loginCard.add(passwordIn);
loginCard.add(separatorPass);
loginCard.add(passLabel);
loginCard.add(btnLogin);
loginCard.add(btnRegister);
loginCard.add(registerLabel);
// SIGNUP //
joinCard = new JPanel();
joinCard.setLayout(null);
emailNew.setBounds(348, 62, 327, 35);
emailNew.setColumns(10);
emailNew.setFont(avenir);
emailNew.setBorder(null);
emailNew.setEditable(false);
usernameNew.setBounds(348, emailNew.getY() + 74, 327, 35);
usernameNew.setColumns(10);
usernameNew.setFont(avenir);
usernameNew.setBorder(null);
passwordNew.setBounds(348, usernameNew.getY() + 74, 327, 35);
passwordNew.setColumns(10);
passwordNew.setFont(avenir);
passwordNew.setBorder(null);
passwordNew2.setBounds(348, passwordNew.getY() + 74, 327, 35);
passwordNew2.setColumns(10);
passwordNew2.setFont(avenir);
passwordNew2.setBorder(null);
//32, 106, 180, 254 : 2, 76, 150, 224
newEmailLabel.setBounds(emailNew.getX(), emailNew.getY() - 20, labelWidth, 16);
newEmailLabel.setFont(avenir);
newUserLabel.setBounds(usernameNew.getX(), usernameNew.getY() - 20, labelWidth, 16);
newUserLabel.setFont(avenir);
newPassLabel.setBounds(passwordNew.getX(), passwordNew.getY() - 20, labelWidth, 16);
newPassLabel.setFont(avenir);
newPassLabel2.setBounds(passwordNew2.getX(), passwordNew2.getY() - 20, labelWidth, 16);
newPassLabel2.setFont(avenir);
btnSignUp.setBounds(348, passwordNew2.getY() + 71, 327, 45); //335 // +81
btnSignUp.addActionListener(this);
btnBack.setBounds(btnSignUp.getX()-70, btnSignUp.getY(), 70, 45); //380
btnBack.addActionListener(this);
joinCard.setBackground(new Color(0, 0, 0, trasparancy));
emailNew.setBackground(new Color(0, 0, 0, 0));
emailNew.setForeground(textColor);
usernameNew.setBackground(new Color(0, 0, 0, 0));
usernameNew.setForeground(textColor);
passwordNew.setBackground(new Color(0, 0, 0, 0));
passwordNew.setForeground(textColor);
passwordNew2.setBackground(new Color(0, 0, 0, 0));
passwordNew2.setForeground(textColor);
newEmailLabel.setForeground(disabledTipColor);
newUserLabel.setForeground(tipColor);
newPassLabel.setForeground(tipColor);
newPassLabel2.setForeground(tipColor);
btnSignUp.setForeground(new Color(70, 130, 180));
btnBack.setBackground(Color.WHITE);
separatorMailNew.setBounds(emailNew.getX(), emailNew.getY()+emailNew.getHeight()-8, emailNew.getWidth(), 6);
separatorMailNew.setForeground(textLine);
separatorUserNew.setBounds(usernameNew.getX(), usernameNew.getY()+usernameNew.getHeight()-8, usernameNew.getWidth(), 6);
separatorUserNew.setForeground(textLine);
separatorPassNew.setBounds(passwordNew.getX(), passwordNew.getY()+passwordNew.getHeight()-8, passwordNew.getWidth(), 6);
separatorPassNew.setForeground(textLine);
separatorPassNew2.setBounds(passwordNew2.getX(), passwordNew2.getY()+passwordNew2.getHeight()-8, passwordNew2.getWidth(), 6);
separatorPassNew2.setForeground(textLine);
joinCard.add(emailNew);
joinCard.add(newEmailLabel);
joinCard.add(usernameNew);
joinCard.add(newUserLabel);
joinCard.add(passwordNew);
joinCard.add(newPassLabel);
joinCard.add(passwordNew2);
joinCard.add(newPassLabel2);
joinCard.add(btnSignUp);
joinCard.add(btnBack);
joinCard.add(separatorMailNew);
joinCard.add(separatorUserNew);
joinCard.add(separatorPassNew);
joinCard.add(separatorPassNew2);
// End //
JPanel whiteRectLogin = new JPanel();
whiteRectLogin.setBackground( Color.WHITE );
whiteRectLogin.setBounds(0, 0, 250, height);
loginCard.add(whiteRectLogin);
JPanel whiteRectJoin = new JPanel();
whiteRectJoin.setBackground( Color.WHITE );
whiteRectJoin.setBounds(0, 0, 250, height);
joinCard.add(whiteRectJoin);
cards = new JPanel(new CardLayout());
cards.setBackground(new Color(0, 0, 0, trasparancy));
cards.add(loginCard, BACK);
cards.add(joinCard, REGISTER);
getContentPane().add(cards);
//Top, Left, bottom, right
ComponentMover cm = new ComponentMover(this, this);
cm.setEdgeInsets(new Insets(-50, 1, 0, -50));
validate();
repaint();
getContentPane().setLayout(null);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnRegister) {
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, REGISTER);
loginCard.setVisible(false);
}
if(e.getSource() == btnBack) {
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, BACK);
loginCard.setVisible(false);
}
if(e.getSource() == btnSignUp) {
//new SignUpCheck();
}
}
public static void main(String[] args) {
new ClientStarter();
}
}
could this be caused because of the transparent background
Probably. Swing does not renderer transparent backgrounds correctly. Swing expects a component to be either fully opaque or fully transparent.
Check out Backgrounds With Transparency for a complete description of the problem and a couple of solutions.
You can either do custom painting of every component with code something like:
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);
Or you can use the AlphaContainer class to do the painting for you.
Also, you have several other problems:
Don't use static variables for your Swing components. That is no the proper usage of the static keyword.
Don't use a null layout and setBounds(). Swing was designed to be used with layout managers. Layout managers work well on multiple platforms.
Don't use an alpha value of 0. The 0 means fully transparent, so just use the setOpaque(false) method on the component.
Don't keep creating new Color objects. The same Color object can be used for every component. It save resources and makes it easier to change all Color for all components all at once.
Don't use validate() and repaint() in the constructor of your class. All the components should be added to the frame BEFORE you invoke setVisible(true) so those methods are not required.
I want to be able to validate a number of different JTextFields in my java project. One being to ensure the user enters a number into a particular field.
Another problem I'm having is being able to validate a particular number, such as 1234 in a field when a submit button is pressed.
If I have to create a method in a separate class then that fine but how would I call the method into my GUI class to use for my JTextField.
I'm quite new to Java and find some of this hard so any help is greatly appreciated.
At the minute I have:
import java.awt.BorderLayout;
public class CashDialog extends JDialog {
private final JPanel contentPanel = new JPanel();
private JTextField txtEmilysBistro;
private JTextField textconfirmNumber;
private String confirmNumber;
private JButton btnSubmit;
/**
* Launch the application.
*/
public static void main(String[] args) {
try {
CashDialog dialog = new CashDialog();
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Create the dialog.
*/
public CashDialog() {
this.confirmNumber = confirmNumber;
setBounds(100, 100, 526, 372);
getContentPane().setLayout(new BorderLayout());
contentPanel.setBackground(new Color(255, 0, 153));
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
contentPanel.setLayout(null);
{
txtEmilysBistro = new JTextField();
txtEmilysBistro.setBackground(new Color(255, 0, 153));
txtEmilysBistro.setHorizontalAlignment(SwingConstants.CENTER);
txtEmilysBistro.setForeground(new Color(255, 255, 255));
txtEmilysBistro.setFont(new Font("AR ESSENCE", Font.PLAIN, 50));
txtEmilysBistro.setEditable(false);
txtEmilysBistro.setText("Emily's Bistro");
txtEmilysBistro.setBounds(0, 0, 504, 57);
contentPanel.add(txtEmilysBistro);
txtEmilysBistro.setColumns(10);
}
JTextArea txtrConfirm = new JTextArea();
txtrConfirm.setForeground(new Color(255, 255, 255));
txtrConfirm.setBackground(new Color(255, 0, 153));
txtrConfirm.setEditable(false);
txtrConfirm.setFont(new Font("AR ESSENCE", Font.PLAIN, 25));
txtrConfirm.setText("Please allow your waiter/waitress to enter the confirmation number.");
txtrConfirm.setBounds(54, 73, 407, 77);
contentPanel.add(txtrConfirm);
txtrConfirm.setLineWrap(true);
textconfirmNumber = new JTextField();
textconfirmNumber.setFont(new Font("AR ESSENCE", Font.PLAIN, 30));
textconfirmNumber.setBounds(147, 148, 227, 47);
contentPanel.add(textconfirmNumber);
textconfirmNumber.setColumns(10);
btnSubmit = new JButton("Submit");
btnSubmit.setBackground(new Color(102, 51, 255));
btnSubmit.setForeground(new Color(255, 255, 255));
btnSubmit.setFont(new Font("AR ESSENCE", Font.PLAIN, 25));
btnSubmit.setBounds(184, 211, 162, 29);
contentPanel.add(btnSubmit);
}
}
In this particular text field I only want it to accept the number 1234 in the text field.
There are a few issues with your code, but that is beside the point. To address your question specifically here is one approach. Grant it, you'd probably want to handle it differently, verify you are getting an integer instead of comparing strings, but still this is how you'd add a listener to your submit button.
btnSubmit.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent arg0)
{
final String data = txtrConfirm.getText();
if( data.compareTo("1234") != 0 )
{
// alert the user
}
else
{
// data is good, do something with it
}
}
});
For some reason my scrollbar is appearing but it is not working. What is suppose to happen is using the scrollbar to scroll through the text of the textarea. Can somebody please explain why this isnt working?
import java.io.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class App extends JFrame{
private JPanel paneel;
public App(){
paneel = new AppPaneel();
setContentPane(paneel);
}
public static void main(String args[]){
JFrame frame = new App();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setTitle("Auto Clicker");
frame.setVisible(true);
}
}
class AppPaneel extends JPanel{
private JTextField delayField, xLocation, yLocation;
private JTextArea listArea;
private JButton addButton, saveButton, runButton;
private JScrollPane scroll;
public AppPaneel(){
setLayout(null);
delayField = new JTextField();
delayField.setBounds(10, 10, 85, 25);
delayField.setText("delay in ms");
xLocation = new JTextField();
xLocation.setBounds(105, 10, 85, 25);
xLocation.setText("X position");
yLocation = new JTextField();
yLocation.setBounds(200, 10, 85, 25);
yLocation.setText("Y position");
addButton = new JButton("Add");
addButton.setBounds(295, 10, 75, 24);
addButton.addActionListener(new AddHandler());
listArea = new JTextArea();
listArea.setBounds(10, 45, 360, 180);
scroll = new JScrollPane(listArea);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scroll.setBounds(370, 45, 20, 180);
saveButton = new JButton("Save");
saveButton.setBounds(10, 230, 85, 24);
runButton = new JButton("Run (F1)");
runButton.setBounds(105, 230, 85, 24);
runButton.addActionListener(new RunHandler());
add(delayField);
add(xLocation);
add(yLocation);
add(addButton);
add(listArea);
add(saveButton);
add(runButton);
add(scroll);
}
class AddHandler implements ActionListener{
public void actionPerformed(ActionEvent a){
listArea.setText(listArea.getText() + delayField.getText() + ", " + xLocation.getText() + ", " + yLocation.getText() + ", " + "click;" + "\n");
}
}
class RunHandler implements ActionListener{
private Robot bot;
private String text;
int foo = Integer.parseInt("1234");
public void actionPerformed(ActionEvent b) {
try{
text = listArea.getText();
bot = new Robot();
for(String line : text.split("\\n")){
int delay = Integer.parseInt((line.substring(0, 4)));
int xpos = Integer.parseInt((line.substring(6, 10)));
int ypos = Integer.parseInt((line.substring(12, 16)));
bot.mouseMove(xpos, ypos);
Thread.sleep(delay);
bot.mousePress(InputEvent.BUTTON1_MASK);
bot.mouseRelease(InputEvent.BUTTON1_MASK);
}
}
catch (AWTException | InterruptedException e){
e.printStackTrace();
}
}
}
}
Don't use null layouts and setBounds as it is messing up your program. We tell folks time and time again not to do this for a reason -- by setting the JTextArea's bound you constrain its size so it won't grow when it needs to. The solution, as always -- learn and use the layout managers. Set the JTextArea's column and row properties but not its bounds, its size, or its preferred size.
Next don't do this: Thread.sleep(delay); in your Swing application as it will put the entire application to sleep. Use a Swing Timer instead for any delays. The tutorials can help you use this.
For a non-functional layout example:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.*;
#SuppressWarnings("serial")
public class App2 extends JPanel {
private static final int GAP = 5;
private JTextField textField1 = new JTextField(GAP);
private JTextField textField2 = new JTextField(GAP);
private JTextField textField3 = new JTextField(GAP);
private JTextArea textArea = new JTextArea(15, 30);
public App2() {
JPanel topPanel = new JPanel(new GridLayout(1, 0, GAP, GAP));
topPanel.add(textField1);
topPanel.add(textField2);
topPanel.add(textField3);
topPanel.add(new JButton("Add"));
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel bottomPanel = new JPanel(new GridLayout(1, 0, GAP, GAP));
bottomPanel.add(new JButton("Save"));
bottomPanel.add(new JButton("Run (F1)"));
bottomPanel.add(new JLabel(""));
bottomPanel.add(new JLabel(""));
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
setLayout(new BorderLayout(GAP, GAP));
add(topPanel, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Auto Clicker");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new App2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Your whole approach is wrong. You should not be using a null layout. For example:
scroll.setBounds(370, 45, 20, 180);
you are setting the width to 20. Well how to you expect the text area to display in 20 pixels? This is the problem with using setBounds(...), the random numbers you use have no meaning. Let a layout manager do its job. Also:
add(listArea);
The problem is that a component can only have a single parent. You originally created the JScrollPane with the text area which is correct.
But then you add the text area directly to the frame which removes it from the scroll pane so the scroll panel will no longer function.
Get rid of that statement and just add the scroll pane to the frame.
However, I don't recommend you use this as your final solution. I just wanted to mention the current problems so you hopefully understand the benefits of using layout managers and so that you don't try to share components again.
The proper solution is to use layout managers as has been suggested by the "Community Wiki". Then the layout manager will determine the size and location of each component so you don't need to worry about calculating your pixel values correctly.
I am new in Java and am doing some window application for my college.
I am trying to do some kind of menu with three buttons in start, and when one of buttons is clicked it's supposed to create a JPanel with two more buttons, but my code doesn't work.
Here is the code:
import java.awt.*;
public class mainScreen extends JFrame {
private JPanel contentPane;
public mainScreen() {
super("Aplikacija za atletska natjecanja");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setBounds(0, 0, screenSize.width, screenSize.height);
contentPane = new JPanel();
contentPane.setBackground(SystemColor.info);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
setContentPane(contentPane);
JPanel top = new JPanel();
top.setBounds(200, 11, screenSize.width - 400, screenSize.height - (screenSize.height - 100));
contentPane.add(top);
JPanel mainMenu = new JPanel();
mainMenu.setBounds(200, 110, screenSize.width - 400, screenSize.height - (screenSize.height - 30));
contentPane.add(mainMenu);
mainMenu.setLayout(new GridLayout(1, 0, 0, 0));
JButton btnTrkacke = new JButton("Trka\u010Dke");
btnTrkacke.setBackground(SystemColor.text);
mainMenu.add(btnTrkacke);
btnTrkacke.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JPanel panTrk = new JPanel();
panTrk.setBounds(201, 140, (screenSize.width - 400) / 3, 30);
contentPane.add(panTrk);
panTrk.setLayout(new GridLayout(1, 0, 0, 0));
JButton btnTrkAtl = new JButton("Atleti\u010Dari");
btnTrkAtl.setBackground(SystemColor.text);
panTrk.add(btnTrkAtl);
JButton btnTrkDisc = new JButton("Discipline");
btnTrkDisc.setBackground(SystemColor.text);
panTrk.add(btnTrkDisc);
}
});
JButton btnSkakacke = new JButton("Skaka\u010Dke");
btnSkakacke.setBackground(SystemColor.text);
mainMenu.add(btnSkakacke);
JButton btnBacacke = new JButton("Baca\u010Dke");
btnBacacke.setBackground(SystemColor.text);
mainMenu.add(btnBacacke);
}
}
That same panel should also be created when I click on the other two buttons, but on other the position... Is it better to create class for that pane and then call it when button is clicked?
You're forgetting to call revalidate and repaint on the contentPane after changing its components:
contentPane.revalidate();
contentPane.repaint();
e.g.,
#Override
public void actionPerformed(ActionEvent e) {
JPanel panTrk = new JPanel();
panTrk.setBounds(201, 140, (screenSize.width - 400) / 3, 30);
contentPane.add(panTrk);
panTrk.setLayout(new GridLayout(1, 0, 0, 0));
JButton btnTrkAtl = new JButton("Atleti\u010Dari");
btnTrkAtl.setBackground(SystemColor.text);
panTrk.add(btnTrkAtl);
JButton btnTrkDisc = new JButton("Discipline");
btnTrkDisc.setBackground(SystemColor.text);
panTrk.add(btnTrkDisc);
contentPane.revalidate(); // ***** added *****
contentPane.repaint(); // ***** added *****
}
revalidate tells the container to re-lay out its components.
repaint requests to the paint manager that the component and any children should be re-drawn.
As an aside: you're using null layout manager and absolute positioning with setBounds(...), and you really don't want to do this. While to a newbie this seems the best way to create complex GUI's, the more you deal with Swing GUI creation, the more you will find that doing this will put your GUI in a straight-jacket, painting it in a very tight corner and making it very hard to extend or enhance. Just don't do this.
will ask here, coz its same project
so it shuld work like this.... 3 buttons, and under each button is hiden panel with two button, so whan some button is clicked under him shuld show panel, whan some ather button is clicked under him shuld show panel, but ather two panels shuld hide.... and this works great until some button is clicked 2 time in a row, after that whan i click some ather button panel under that button dont wont to hide..
here is the code
JPanel mainMenu = new JPanel();
mainMenu.setBounds(200, 110, screenSize.width - 400, screenSize.height - (screenSize.height - 30));
contentPane.add(mainMenu);
mainMenu.setLayout(new GridLayout(1, 0, 0, 0));
JButton btnTrkacke = new JButton("Trka\u010Dke");
btnTrkacke.setBackground(SystemColor.text);
mainMenu.add(btnTrkacke);
btnTrkacke.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panTrk = new JPanel();
panTrk.setBounds(201, 140, (screenSize.width - 400) / 3, 30);
contentPane.add(panTrk);
panTrk.setLayout(new GridLayout(1, 0, 0, 0));
JButton btnTrkAtl = new JButton("Atleti\u010Dari");
btnTrkAtl.setBackground(SystemColor.text);
panTrk.add(btnTrkAtl);
JButton btnTrkDisc = new JButton("Discipline");
btnTrkDisc.setBackground(SystemColor.text);
panTrk.add(btnTrkDisc);
contentPane.revalidate();
contentPane.repaint();
panSka.setVisible(false);
panBac.setVisible(false);
}
});
JButton btnSkakacke = new JButton("Skaka\u010Dke");
btnSkakacke.setBackground(SystemColor.text);
mainMenu.add(btnSkakacke);
btnSkakacke.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panSka = new JPanel();
panSka.setBounds(201 + (screenSize.width - 400) / 3, 140, (screenSize.width - 400) / 3, 30);
contentPane.add(panSka);
panSka.setLayout(new GridLayout(1, 0, 0, 0));
JButton btnSkaAtl = new JButton("Atleti\u010Dari");
btnSkaAtl.setBackground(SystemColor.text);
panSka.add(btnSkaAtl);
JButton btnSkaDisc = new JButton("Discipline");
btnSkaDisc.setBackground(SystemColor.text);
panSka.add(btnSkaDisc);
contentPane.revalidate();
contentPane.repaint();
panTrk.setVisible(false);
panBac.setVisible(false);
}
});
JButton btnBacacke = new JButton("Baca\u010Dke");
btnBacacke.setBackground(SystemColor.text);
mainMenu.add(btnBacacke);
btnBacacke.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panBac = new JPanel();
panBac.setBounds(201 + (screenSize.width - 400) / 3 * 2, 140, (screenSize.width - 400) / 3, 30);
contentPane.add(panBac);
panBac.setLayout(new GridLayout(1, 0, 0, 0));
JButton btnBacAtl = new JButton("Atleti\u010Dari");
btnBacAtl.setBackground(SystemColor.text);
panBac.add(btnBacAtl);
JButton btnBacDisc = new JButton("Discipline");
btnBacDisc.setBackground(SystemColor.text);
panBac.add(btnBacDisc);
contentPane.revalidate();
contentPane.repaint();
panSka.setVisible(false);
panTrk.setVisible(false);
}
});
I am trying to make a program to java and i have the common problem with flickering. I have try many things to eliminate but all the same. while the oval that i paint is moving the japplet is flickering. i need your help to solve this problem. here is my code:
import java.awt.Color;
public class all extends JApplet implements Runnable {
double x=0;
double y=0;
int m=0;
int n=0;
int f=30;
int μ=0;
Thread kinisi;
JPanel panel;
JFrame frame;
private boolean running = false;
private JTextField textField1;
private JTextField textField2;
Image backGround;
JPanel panel_3;
Image bf = createImage(m, n);
private Graphics doubleg;
private Image i;
public void init() {
this.setSize(800, 700);
}
public all() {
getContentPane().setLayout(null);
JButton btnNewButton = new JButton("Start");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
String b=textField2.getText();
String z =textField1.getText();
if (textField1.getText().equals("") ||
textField2.getText().equals("")){
JOptionPane.showMessageDialog(
new JFrame(),
"Δωστε τιμή για το φ και το μ!",
"ERROR",JOptionPane.ERROR_MESSAGE);
} else{
f = Integer.parseInt(b);
μ = Integer.parseInt(z);
Start(); }
}
});
btnNewButton.setBounds(469, 168, 89, 23);
getContentPane().add(btnNewButton);
JButton btnStop = new JButton("Pause");
btnStop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
pause();
}
});
btnStop.setBounds(588, 168, 89, 23);
getContentPane().add(btnStop);
JButton btnReset = new JButton("Reset");
btnReset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Reset();
}
});
btnReset.setBounds(701, 168, 89, 23);
getContentPane().add(btnReset);
JLabel label = new JLabel("\u03BC");
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setBounds(549, 63, 46, 14);
getContentPane().add(label);
textField1 = new JTextField();
textField1.setBounds(529, 101, 86, 20);
getContentPane().add(textField1);
textField1.setColumns(10);
JLabel label_1 = new JLabel("\u03C6");
label_1.setHorizontalAlignment(SwingConstants.CENTER);
label_1.setBounds(681, 63, 46, 14);
getContentPane().add(label_1);
textField2 = new JTextField();
textField2.setBounds(667, 101, 86, 20);
getContentPane().add(textField2);
textField2.setColumns(10);
JButton btnNewButton_1 = new JButton("");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(
new JFrame(),
"Οδηγίες προγράμματος","Οδηγίες",
JOptionPane.INFORMATION_MESSAGE);
}
});
btnNewButton_1.setIcon(
new ImageIcon(all.class.getResource("/Images/info.png")));
btnNewButton_1.setBounds(732, 5, 39, 35);
getContentPane().add(btnNewButton_1);
JLabel label_2 = new JLabel("");
label_2.setIcon(
new ImageIcon(all.class.getResource("/Images/earth.jpg")));
label_2.setBounds(-20, 0, 820, 361);
getContentPane().add(label_2);
JPanel panel_1 = new JPanel();
panel_1.setBorder(
new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
panel_1.setBounds(10, 372, 369, 290);
getContentPane().add(panel_1);
JPanel panel_2 = new JPanel();
panel_2.setBorder(
new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
panel_2.setBounds(408, 372, 369, 290);
getContentPane().add(panel_2);
}
public void paint(Graphics g){
super.paint(g);
g.drawLine(0,f,350,200);
g.drawLine(0,200,350,200);
g.drawOval(m,n,40,40);
Color brown=new Color(137,66,0);
g.setColor(brown);
g.fillOval(m, n, 40, 40);
//Graphics2D g2d = (Graphics2D) g;
g.drawLine(460,400,460,650);
g.drawLine(20, 620, 350, 620);
g.drawLine(50,400,50,650);
g.drawLine(430, 620, 760, 620);
}
public void Start() {
kinisi = new Thread(this);
kinisi.start();
running = true;
}
public void run() {
while (running) {
if (x < 340){
double l = 200-f;
double k = l/350;
double y=k*x+f-30;
x= x+1;
m = (int) x;
n = (int) y;
repaint();
try {
Thread.sleep(μ);
} catch (InterruptedException ie) {}
}
}
}
public void update(Graphics g) {
if(i==null){
i=createImage(800,700);
doubleg = i.getGraphics();
}
doubleg.setColor(getBackground());
doubleg.fillRect(0,0,800,700);
doubleg.setColor(getForeground());
paint(doubleg);
g.drawImage(i,0,0,this);
}
public void paint1(Graphics g){
g.drawLine(0, f ,350, 200);
g.drawOval(m, n, 40, 40);
Color brown=new Color(137,66,0);
g.setColor(brown);
g.fillOval(m, n, 40, 40);
}
public void pause() {
if (kinisi != null) {
running = false;
}
}
public boolean Reset() {
if (kinisi != null) {
running = false;
kinisi.interrupt();
kinisi = null;
x=0;
y=0;
f=30;
m=0;
n=0;
repaint();
textField1.setText("");
textField2.setText("");
}
Graphics g = getGraphics();
g.drawOval(m,n,40,40);
Color brown=new Color(137,66,0);
g.setColor(brown);
g.fillOval(m, n, 40, 40);
return false;
}
public static void main(String[] args) {
JFrame frame = new JFrame("FISIKI");
frame.getContentPane().add(new all());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 700);
frame.setVisible(true);
frame.setResizable(false);
}
}
Thank you very much and sorry for my english are not very good!
There are a number of things that jump out at me.
You're extending from JApplet, but are adding it to a JFrame
You're mixing components with you custom painting
Not using layout managers.
Using getGraphics.
Firstly...
You should never override paint of a top level container (like JApplet). There are many reasons and you've found one. Top level containers are not double buffered. Instead, you should be creating a custom component (by extending something like JPanel) and overriding it's paintComponent method...
Secondly
Decided how you application is going to be. Is it an applet or application? If you follow the first point, then it really doesn't matter, as you only simply need to add the panel to the top level container.
Thirdly
I would create a panel that did the custom painting. Then I would create separate containers for all the fields and other parts of the application. This will allow you to separate the areas of responsibility. It would also allow you to use layout managers ;)
Fourthly
Use layout managers. The layout manager API has being designed to solve one of this most annoying aspects of GUI design, you're asking for a lot of trouble and work you decided to discard it - IMHO.
Fifthly
getGraphics should never be used. Apart from the fact that it can return null, it is only a snap shot of what is currently on the screen. As soon as the RepaintManager decides to perform a repaint, anything rendered to it will be lost. You should use paintComponent to update the state of your custom pane.