I am trying to create small GUI with couple of textboxes. Shortest code is here:
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class MortgageCalculator implements ActionListener {
JTextField loanAmount, loanTerm;
JFrame jf;
public static void main(String[] args) {
// TODO Auto-generated method stub
mygui mg = new mygui();
mg.initUIPanel();
}
public void initUIPanel() {
jf = new JFrame();
jf.setTitle("my gui");
jf.setLocation(300, 400);
jf.setSize(400, 500);
jf.setVisible(true);
jf.setResizable(false);
jf.show();
JPanel panel = new JPanel();
panel.setLayout(null);
loanAmount = new JTextField(15);
loanAmount.setBounds(170, 20, 125, 20);
loanTerm = new JTextField(15);
loanTerm.setBounds(170, 60, 125, 20);
panel.add(loanAmount);
panel.add(loanTerm);
jf.add(panel, "Center");
}
}
The problem is it displays only the frame but not the txtboxes. I can see the boxes only after maximizing the frame once. If minimize it again, then still I can see them, but not at first. What am i doing wrong ?
Try to get rid of this, so JPanel will use default FlowLayout layout manager
panel.setLayout(null);
You can read more here -> layouts managers
Related
Iam trying to build a desktop application with multiple screens inside one single JFrame.
So each button click event will take us to the separate screen with refreshed components in the screen. So far this approach is working for me but the problem I am facing is even after using ".dispose(), .repaint(), .revalidate(), .invalidate()" functions. JInternalFrame or Jpanel seems to not refresh its components.
Which works something like below gif.
Tabbed Style
I do know JtabbedPane exists but for my method JtabbedPane is not viable.
Below I am posting minified code by replicating the problem I am facing.
MainMenu.Java(file with Main Class)
package test;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JInternalFrame;
public class MainMenu extends JFrame {
private JPanel contentPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainMenu frame = new MainMenu();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public MainMenu() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 841, 522);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JPanel panel = new JPanel();
panel.setBounds(10, 10, 807, 63);
contentPane.add(panel);
panel.setLayout(new GridLayout(1, 0, 0, 0));
JButton Tab1 = new JButton("Tab1");
panel.add(Tab1);
JButton Tab2 = new JButton("Tab2");
panel.add(Tab2);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 88, 807, 387);
contentPane.add(scrollPane);
JInternalFrame internalFrame1 = new JInternalFrame();
JInternalFrame internalFrame2 = new JInternalFrame();
Tab1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Panel1 panel1 = new Panel1();
if(internalFrame1 !=null) {
internalFrame1.dispose();
panel1.invalidate();
panel1.revalidate();
panel1.repaint();
}
internalFrame1.setTitle("Panel 1");
scrollPane.setViewportView(internalFrame1);
internalFrame1.getContentPane().add(panel1);
internalFrame1.setVisible(true);
}
});
Tab2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Panel2 panel2 = new Panel2();
if(internalFrame2 !=null) {
internalFrame2.dispose();
panel2.invalidate();
panel2.revalidate();
panel2.repaint();
}
internalFrame2.setTitle("Panel 2");
scrollPane.setViewportView(internalFrame2);
internalFrame2.getContentPane().add(panel2);
internalFrame2.setVisible(true);
}
});
}
}
and the corresponding Jpanel class files where JInternal Frames
Panel1.java
package test;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
public class Panel1 extends JPanel {
private JTextField textField;
/**
* Create the panel.
*/
public Panel1() {
setLayout(null);
textField = new JTextField();
textField.setBounds(10, 60, 430, 19);
add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("Example Button");
btnNewButton.setBounds(10, 156, 430, 21);
add(btnNewButton);
}
}
Panel2.java
package test;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
public class Panel2 extends JPanel {
private JTextField textField;
/**
* Create the panel.
*/
public Panel2() {
setLayout(null);
textField = new JTextField();
textField.setBounds(10, 60, 430, 19);
add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("New button2");
btnNewButton.setBounds(21, 157, 419, 21);
add(btnNewButton);
}
}
P.S: This is my first time asking question in Stackoverflow so forgive me and if possible guide me if i miss anything
Thank you :)
Edit:
The problem I am facing is on the surface it looks like the Jpanel has been refreshed but the components like JtextField Still hides the previously written text in it and only show the text when i click on that JTextField
Below I am Attaching another gif which show highlights the issue. I have highlighted the part where I am facing issue.
Issue I am Facing
The dispose() method does not remove components so you keep adding components to the internal frame when you use the following:
internalFrame1.getContentPane().add(panel1);
Instead you might do something like:
Container contentPane = internalFrame1.getContentPane();
contentPane.removeAll();
contentPane.add( panel1 );
contentPane.revalidate();
contentPane.repaint();
You can use the JPanels in the Jframes and then use the CardLayout to change the panel ( which could than act like the different screens )
As the title, I want to create two buttons in java swing and these two buttons can overlap each other (as image). I searched the internet but I could not find it.
Thanks so much
You can simply do this by setting the JFrame layout to Absolute Layout, and adding a JButton on top of another JButton. Make sure the small button is on top of the other button in the navigator.
You can use an OverlayLayout here.
An SSCCE (with comments inside) would be:
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.OverlayLayout;
import javax.swing.SwingUtilities;
public class OverlayLayoutExample extends JFrame {
JPanel overlayoutPanel;
JButton jButton2, jButton1;
public OverlayLayoutExample() {
overlayoutPanel = new JPanel() {
#Override
public boolean isOptimizedDrawingEnabled() {
//Required to have always visible both components
return false;
}
};
OverlayLayout overlay = new OverlayLayout(overlayoutPanel);
overlayoutPanel.setLayout(overlay);
jButton1 = new JButton("jButton");
Dimension d1 = new Dimension(350, 100);
jButton1.setMaximumSize(d1);
jButton1.setAlignmentX(0.7f); //Some X-Y values, play with them
jButton1.setAlignmentY(0.65f); //Some X-Y values, play with them
jButton2 = new JButton("jButton2");
Dimension d2 = new Dimension(100, 25);
jButton2.setMaximumSize(d2);
jButton2.setAlignmentX(0.01f); //Some X-Y values, play with them
jButton2.setAlignmentY(0.01f); //Some X-Y values, play with them
overlayoutPanel.add(jButton2); //First the top component
overlayoutPanel.add(jButton1); //Then the above component
getContentPane().add(overlayoutPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300, 300);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(() -> new OverlayLayoutExample().setVisible(true));
}
}
More about isOptimizedDrawingEnabled() can be found here.
Preview:
You can do this using the layered pane of JFrame like this:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
public class ButtonOnTop
{
public static void main(String[] args)
{
JButton button1 = new JButton("jButton1");
button1.setBounds(30, 50, 260, 160);
JButton button2 = new JButton("jButton2");
button2.setBounds(150, 150, 100, 40);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLayeredPane layeredPane = f.getLayeredPane();
layeredPane.add(button1, Integer.valueOf(0));
layeredPane.add(button2, Integer.valueOf(1));
f.setBounds(300, 200, 400, 300);
f.setVisible(true);
}
}
Please look below for Edits.
So I've looking over numerous "solutions" to fix my problem, but I just can't seem to get it working.
This is what my application looks like with the code below:
Basically, I want to set the location of a button, but I can't manage to do so. Here is my code:
package me.cervinakuy.application;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ControlPanel3 extends JFrame {
JPanel panel = new JPanel();
JButton startRobo = new JButton();
JButton stopRobo = new JButton();
JButton restartRobo = new JButton();
public ControlPanel3() {
// setLayout(null);
setSize(1000, 700);
setResizable(false);
setLocation(450, 150);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setBackground(new Color(45, 48, 55));
setTitle("Espin Software | Control Panel");
setVisible(true);
startRobo.setIcon(new ImageIcon(getClass().getResource("/resources/startRobo.png")));
stopRobo.setIcon(new ImageIcon(getClass().getResource("/resources/stopRobo.png")));
restartRobo.setIcon(new ImageIcon(getClass().getResource("/resources/restartRobo.png")));
startRobo.setBorder(null);
stopRobo.setBorder(null);
restartRobo.setBorder(null);
startRobo.setLocation(100, 100);
panel.add(startRobo);
panel.add(stopRobo);
panel.add(restartRobo);
panel.setOpaque(false);
add(panel);
validate();
}
}
EDIT:
I have now managed to create a GUI of what I was initially looking for, however, I have a new problem. Buttons are now pressable from different parts of the GUI, rather than only on the image. For those interested, here is what I have been able to accomplish:
New GUI look.
Updated Code:
package me.cervinakuy.application;
import java.awt.Color;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ControlPanel3 extends JFrame {
JPanel panel = new JPanel();
JButton startRobo = new JButton();
JButton stopRobo = new JButton();
JButton restartRobo = new JButton();
public ControlPanel3() {
// setLayout(null);
setSize(1000, 700);
setResizable(false);
setLocation(450, 150);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setBackground(new Color(45, 48, 55));
setTitle("Espin Software | Control Panel");
setVisible(true);
startRobo.setIcon(new ImageIcon(getClass().getResource("/resources/startRobo.png")));
stopRobo.setIcon(new ImageIcon(getClass().getResource("/resources/stopRobo.png")));
restartRobo.setIcon(new ImageIcon(getClass().getResource("/resources/restartRobo.png")));
startRobo.setBorder(null);
stopRobo.setBorder(null);
restartRobo.setBorder(null);
panel.setLayout(null);
startRobo.setLocation(200, 200);
startRobo.setBounds(5, -95, 300, 300);
stopRobo.setBounds(5, 0, 300, 300);
restartRobo.setBounds(5, 95, 300, 300);
panel.add(startRobo);
panel.add(stopRobo);
panel.add(restartRobo);
panel.setOpaque(false);
add(panel);
validate();
}
}
There are typically a number of ways to layout components that end with the same effect. In this example, we use a panel to contain the buttons in a column (buttonContainer using a GridLayout) then a panel to restrict that container to the top (buttonConstrainPanel using a BorderLayout) then a container to put that panel on the left (ui with BorderLayout).
It could also be achieved using a single GridBagLayout or a GroupLayout, though the logic of achieving it might not be as simple.
The focus border seen on the blue button indicates the limits of where a mouse click would activate the button.
import java.awt.*;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class ThreeButtonAlignedLeft {
private JComponent ui = null;
private String prefix = "http://i.stack.imgur.com/";
private String[] suffix = {"gJmeJ.png","T5uTa.png","wCF8S.png"};
ThreeButtonAlignedLeft() {
try {
initUI();
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
}
public void initUI() throws MalformedURLException {
if (ui!=null) return;
ui = new JPanel(new BorderLayout(4,4));
ui.setBorder(new EmptyBorder(4,4,4,4));
JPanel buttonContainer = new JPanel(new GridLayout(0, 1, 5, 5));
for (int ii=0; ii<suffix.length; ii++) {
JButton b = new JButton(new ImageIcon(new URL(prefix + suffix[ii])));
b.setBorderPainted(false);
b.setMargin(new Insets(0,0,0,0));
b.setContentAreaFilled(false);
buttonContainer.add(b);
}
JPanel buttonConstrainPanel = new JPanel(new BorderLayout(0, 0));
buttonConstrainPanel.add(buttonContainer, BorderLayout.PAGE_START);
ui.add(buttonConstrainPanel, BorderLayout.LINE_START);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
ThreeButtonAlignedLeft o = new ThreeButtonAlignedLeft();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
I want to create an input JFrame where the program reads three fields (model, week and plan), and after inserting one line the user can choose to input new values on a different row, this is done pressing a JLabel with a image add icon.
My expectation is to be able to add a new JPanel (called body in the subclass) right under the last one (JPanel lastContent global variable), and to be able to remove or add new ones as the user needs.
Below is my code so far:
package marquesina;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.jdesktop.swingx.HorizontalLayout;
import org.jdesktop.swingx.VerticalLayout;
public class JModificaciones extends Container {
private JPanel lastContent;
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("DEMO");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the content pane.
JModificaciones mods = new JModificaciones();
frame.setContentPane(mods);
//Display the window.
frame.pack();
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(
dim.width / 2 - frame.getSize().width / 2,
dim.height / 2 - frame.getSize().height / 2);
frame.setVisible(true);
});
}
public JModificaciones() {
initComponents();
System.out.println("New Panel Created");
}
private void initComponents() {
JPanel jHeader = new JPanel();
JLabel jLMod = new JLabel();
JLabel jLSem = new JLabel();
JLabel jLPlan = new JLabel();
JPanel jFooter = new JPanel();
JButton jGuardar = new JButton();
JButton jCancelar = new JButton();
setLayout(new VerticalLayout(10));
//HEADER
jHeader.setLayout(new HorizontalLayout());
jLMod.setText("Model");
jHeader.add(jLMod);
jLWeek.setText("Week");
jHeader.add(jLWeek);
jLPlan.setText("Plan");
jHeader.add(jLPlan);
add(jHeader);
//CONTENT
add(new jContent());
//FOOTER
jGuardar.setText("Save");
jFooter.add(jGuardar);
jCancelar.setText("Cancel");
jFooter.add(jCancel);
add(jFooter);
}
public class jContent extends JPanel {
JLabel jAdd = new javax.swing.JLabel();
JLabel jDelete = new javax.swing.JLabel();
public jContent() {
JPanel body = new JPanel(new HorizontalLayout());
JTextField jModel = new JTextField();
JTextField jWeek = new JTextField();
JTextField jPlan = new JTextField();
body.setLayout(new org.jdesktop.swingx.HorizontalLayout());
jModel.setPreferredSize(new java.awt.Dimension(100, 28));
body.add(jModel);
jWeek.setPreferredSize(new java.awt.Dimension(100, 28));
body.add(jWeek);
jPlan.setPreferredSize(new java.awt.Dimension(100, 28));
body.add(jPlan);
jAdd.setIcon(
new javax.swing.ImageIcon(
getClass().getResource("add.png")));
jAdd.addMouseListener(new java.awt.event.MouseAdapter() {
#Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
}
});
body.add(jAdd);
jDelete.setIcon(
new javax.swing.ImageIcon(
getClass().getResource("delete.png")));
jDelete.addMouseListener(new java.awt.event.MouseAdapter() {
#Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
remove(lastContent);
}
});
body.add(jDelete);
add(body);
}
}
}
However I'm not able to add a new JPanel (which I want to create when the user clicks on the jAdd JLabel), I can't come up with a way to reference the JPanel where I want to put my new Components and using just add() or remove() as I do in the above code just reference the MouseListener, not the JPanel created in the sublcass...
When I edit text in a JTextField in my Swing application on OSX, the text gets garbled. It's most pronounced when I insert or delete characters but there are artifacts just when moving the cursor around. The data is fine, but the UI rendering is not.
What causes this and how can I fix it?
I'm using com.apple.laf.AquaLookAndFeel, as in this sample program. Type in some text and move the cursor around with the arrow keys to observe the weirdness.
import java.awt.*;
import javax.swing.*;
class TextFieldDisplay {
public static void main(String[] args) {
MainWindow app = new MainWindow();
}
}
class MainWindow extends JFrame {
public MainWindow() {
try {
UIManager.setLookAndFeel("com.apple.laf.AquaLookAndFeel");
} catch(Exception e) {
System.out.println("AquaLookAndFeel is not supported on your platform.");
System.exit(1);
}
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
setMinimumSize(new Dimension(300, 100));
JPanel innerPanel = new JPanel();
JScrollPane scrollPane = new JScrollPane();
scrollPane.setPreferredSize(new Dimension(250, 20));
scrollPane.setViewportView(innerPanel);
JPanel mainPanel = new JPanel();
getContentPane().add(mainPanel);
mainPanel.add(innerPanel);
JTextField textField = new JTextField();
textField.setPreferredSize(new Dimension(250, 20));
innerPanel.add(textField);
pack();
}
}
I noticed as I was writing the SSCCE that the display issues seemed to crop up after I added the JScrollPane.
Not sure if it's relevant but I'm using Apple Java version 1.6.0_51 with a retina display.
Two things jump out at me.
Firstly, you're not initalisig your UI in the EDT, secondly, you're messing with the preferred and minimum sizes of your components.
You are not taking into consideration the font metrics when calculating the size of your components, which seems to be causing issues when it is rendering the content
Start by taking a look at Initial Threads.
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
class TextFieldDisplay {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
//UIManager.setLookAndFeel("com.apple.laf.AquaLookAndFeel");
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
System.out.println("AquaLookAndFeel is not supported on your platform.");
System.exit(1);
}
MainWindow app = new MainWindow();
}
});
}
}
class MainWindow extends JFrame {
public MainWindow() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
// setMinimumSize(new Dimension(300, 100));
JPanel innerPanel = new JPanel();
// JScrollPane scrollPane = new JScrollPane();
// scrollPane.setPreferredSize(new Dimension(250, 20));
// scrollPane.setViewportView(innerPanel);
JPanel mainPanel = new JPanel();
getContentPane().add(mainPanel);
mainPanel.add(innerPanel);
JTextField textField = new JTextField(20);
// textField.setPreferredSize(new Dimension(250, 20));
innerPanel.add(textField);
pack();
}
}