add the gui components dynamically? - java

I'm working on a program and I want to create an app in which I can repeat the gui components using the for loop. I've done this using card layout and it works fine but when I use container and JPanel without card layout the gui components overlap on the previous components. Please give me a hint or advise where my code is wrong. Thanks for your advise and time in advance.
Here's the code of my app:
class form extends JFrame implements ActionListener {
JTextArea text;
static int openFrameCount = 0;
public form(){
super("Insert Form");
Container panel=getContentPane();
JPanel cc = new JPanel();
cc.setLayout(null);
for(int i=1;i<=2;i++){
JLabel label1=new JLabel(" Question"+(++openFrameCount));
label1.setBounds(15, 40, 185, 50);
cc.add(label1);
text=new JTextArea();
text.setLineWrap(true);
text.setWrapStyleWord(true);
text.setPreferredSize(new Dimension(750,50));
text.setBounds(80, 60,750,50);
cc.add(text);
JLabel symbol=new JLabel("Selection for Option?");
symbol.setBounds(100, 120,850,60);
cc.add(symbol);
ButtonGroup group = new ButtonGroup();
JRadioButton rbut=new JRadioButton("Radio Button for option");
rbut.setBounds(300, 120,300,60);
JCheckBox cbox=new JCheckBox("Check Box for option");
cc.add(rbut);
cbox.setBounds(650, 120,350,60);
cc.add(cbox);
group.add(rbut);
group.add(cbox);
cc.revalidate();
validate();
panel.add(cc);
}
}

You have set the layout of the cc panel to null, which is not a good idea. Then, using the setBounds(x, y, width, height) you set the location and size of the components that you add and they of course overlap.
Try to use any layout manager that fits your needs, but don't set it to null unless you really have a very strong reason to do that.

Related

Create a blue colored rectangular java bean [duplicate]

public void start_Gui() {
JFrame window = new JFrame("Client Program");
window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
window.setContentPane(panel);
panel.setLayout(new GridLayout(1,2));
JLabel leftside = new JLabel();
leftside.setLayout(new GridLayout(2, 1));
JTextArea rightside = new JTextArea();
rightside.setEditable(false); //add scroll pane.
rightside.setBorder(BorderFactory.createLineBorder(Color.BLACK));
rightside.setLayout(new FlowLayout());
JTextArea client_text_input = new JTextArea();
client_text_input.setBorder(BorderFactory.createLineBorder(Color.BLACK));
leftside.add(client_text_input);
JLabel buttons_layer = new JLabel();
JButton login = new JButton("Login");
JButton logout = new JButton("Logout");
buttons_layer.setBorder(BorderFactory.createLineBorder(Color.BLACK));
buttons_layer.setLayout(new GridLayout(2, 1));
buttons_layer.add(login);
buttons_layer.add(logout);
leftside.add(buttons_layer);
panel.add(leftside);
panel.add(rightside);
window.setSize(300, 400);
window.setResizable(false);
window.setVisible(true);
}
I am working on a simple java chat client gui application. (the server etc, is done by others).
It is not a big project, but my only problem is that whatever I do to try to resize any components on the above GUI, won't work.
For example:
JTextArea client_text_input = new JTextArea();
client_text_input.setSize(100,200);
Won't work.
Thanks for the help.
In Swing, you have two options for layout: do everything manually or let a LayoutManager handle it for you.
Calling setSize() will only work when you're not using a LayoutManager. Since you're using a GridLayout you'll have to use other ways to specify what you want.
Try calling setPreferredSize() and setMinimumSize().
Two things - firstly you should be setting the preferredSize of the scrollpane, but secondly, trying to resize it inside the componentResized handler isn't a very effective technique because the 'resized' events aren't continuous.
check resizing text area in a JFrame
but setXxxSize (for ContainersChilds) works as chaims if you change from setSize() (for TopLayoutContainer) to setPreferredSize() and you have to call pack() before setVisible()

Java/Swing - Set title for TextField

I could not find any class to set a title for TextField. Therefore, I decided to make one. My question is really simple.
Do I really need to include JFrame in my class or maybe there is a different way to accomplish this problem.
Here is my GUI class.
public GUI() {
JFrame f = new JFrame("MyLibrary");
JTextField tf = new JTextField();
tf.setBounds(50, 50, 400, 30);
tf.setFont(new Font("Arial", Font.BOLD, 16));
FieldTitle ft = new FieldTitle(f, tf, "Book title");
f.add(tf);
f.setSize(1280, 720);
f.setLocationRelativeTo(null);
f.setLayout(null);
f.setVisible(true);
}
And here is my FieldTitle class.
public FieldTitle(JFrame f, Component c, String title) {
JLabel l = new JLabel(title);
l.setBounds(c.getBounds().x, c.getBounds().y - 20, c.getWidth(), 20);
f.add(l);
}
Thank you for your time and effort. Have a great day!
Don't use a null layout. Don't use setBounds().
Swing was designed to be used with layout managers. You can easily use a JPanel with a BoxLayout:
Create a JPanel and set the layout to a vertical BoxLayout
Create and add the JLabel to the panel
Create and and the JTextField to the panel
Add the panel to the frame.
Read the Swing tutorial on Layout Managers for more information. You will find a working example that shows how to create a frame with a panel using a BoxLayout.

Displaying a JLabel in front of another JLabel

Game(){
JFrame frame = new JFrame("Display Image");
JPanel panel = (JPanel)frame.getContentPane();
frame.setSize(1000,625);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel();
label.setIcon(new ImageIcon("C:/Users/Ragnar/Desktop/GameBoard.png"));
panel.add(label);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
So i have this constructor ,and i want to add some new JLabels with Images,but i want them to be displayed on top of first image which is the image of the first jLabel label.Can anyone guide me how to achieve this please?I tryed to add them as usually but they are displayed behind the label.
If you have a background image and you want to display the JLabel on top of the background image, you can use a JPanel to hold the background image, then add your JLabel.
Usually if you try to let 2 JLabel overlap each other it won't succeed due to the default layout manager used by the container (such as FlowLayout in JPanel or BorderLayout in JFrame).
If you really want to let them over lap, you will have to set the layout as null. But they may introduce new problems as you lose control over the appearance of your components.
Hence, in cases like this I would usually go for custom painting and draw the images you want in any particular order you are interested in.
For example: How to create a background and foreground image which overlaps?
If you are working with eclipse, and you have installed the windowbuilder plugin you can use the graphical editing view.
Within this view use the contextual menu to order the elements.
What worked for me was, when adding the components with the method add(component), adding them in order from front to back. In the following example I add a lot of components to a JFrame, and the last one to be added is the wallpaper, so it stays at the background.
import java.awt.Image;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class LogIn extends JFrame implements ActionListener{
public static JFrame operador;`enter code here`
private JLabel logo, foot, mensaje, wallpaper;
private JTextField fldUser;
private JPasswordField fldPass;
private JButton entrar;
private int ancho =400, largo= 530;
public static String user="", pass="", name;
public LogIn() {
setLayout(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(ancho,largo);
setResizable(false);
setTitle("Acceso al sitema");
setLocationRelativeTo(null);
setIconImage(getIconImage());
fldUser = new JTextField();
fldUser.setHorizontalAlignment(JTextField.CENTER);
fldUser.setBounds(125,320,150,25);
fldUser.setBackground(new Color(50,50,255));
fldUser.setForeground(Color.WHITE);
fldUser.setBorder(new SoftBevelBorder(BevelBorder.LOWERED));
add(fldUser);
fldPass = new JPasswordField();
fldPass.setHorizontalAlignment(JTextField.CENTER);
fldPass.setBounds(125,360,150,25);
fldPass.setBackground(new Color(50,50,255));
fldPass.setForeground(Color.WHITE);
fldPass.setBorder(new SoftBevelBorder(BevelBorder.LOWERED));
add(fldPass);
mensaje= new JLabel();
mensaje.setBounds(0,390,ancho,15);
mensaje.setForeground(Color.RED);
mensaje.setHorizontalAlignment(SwingConstants.CENTER);
add(mensaje);
entrar =new JButton("Entrar");
entrar.setBounds(125,410,150,40);
entrar.setForeground(new Color(50,50,255));
//entrar.setBorder(new SoftBevelBorder(BevelBorder.RAISED));
entrar.addActionListener(this);
add(entrar);
logo = new JLabel();
logo.setBounds(50,0,300,300);
ImageIcon imgLogo= new ImageIcon("src/images/DS.png");
Icon iconoLogo = new ImageIcon(imgLogo.getImage().getScaledInstance(logo.getWidth(),logo.getHeight(), Image.SCALE_DEFAULT));
logo.setIcon(iconoLogo);
foot = new JLabel("Desarrollado por Gabriel Santos");
foot.setBounds((ancho-200)/2,largo-60,200,30);
//When JLabels overlap, the ones that come to the front are the first to be added to the window.
add(foot);
add(logo);
wallpaper = new JLabel();
wallpaper.setBounds(0,0,window.getWidth(),window.getHeight());
ImageIcon img = new ImageIcon("src/images/wallpaperPrincipal.jpg");
Icon icono = new ImageIcon(img.getImage().getScaledInstance(this.getWidth(),this.getHeight(), Image.SCALE_DEFAULT));
wallpaper.setIcon(icono);
add(wallpaper);
setVisible(true);
}
}

Which Layout should be used?

I'm kind of new to the whole "how to arrange your components" thing in JAVA and I couldn't figure out how to realise the following JFrame (I can't post images so I just put the link)
I tried to be as precise as possible about what I already did.
I would like your advice about how to arrange the green part.
Thanks!
EDIT: as some people rightfully said, I didn't put the code of what I did. Here it is:
public Frame(){
this.setTitle("Small application");
this.setSize(445, 500);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setVisible(true);
this.setResizable(false);
JPanel container = new JPanel();
container.setLayout(new BorderLayout());
//Title
JLabel title = new JLabel("Welcome to this application");
title.setHorizontalAlignment(JLabel.CENTER);
title.setPreferredSize(new Dimension(200,50));
title.setFont(new Font("Courrier",Font.BOLD,20));
container.add(title, BorderLayout.NORTH);
//Center part
JPanel centerPart = new JPanel();
JLabel cell1 = new JLabel("Enter all measurements:");
cell1.setPreferredSize(new Dimension(150,20));
JLabel cell2 = new JLabel("Please, select the files...");
cell2.setPreferredSize(new Dimension(150,20));
cell2.setBackground(Color.white);
cell2.setBorder(BorderFactory.createLineBorder(Color.black));
cell2.setOpaque(true);
JButton cell3 = new JButton("Browse");
cell3.setPreferredSize(new Dimension(100,20));
centerPart.add(cell1);
centerPart.add(cell2);
centerPart.add(cell3);
container.add(centerPart, BorderLayout.CENTER);
/*
* I need your help here :)
* I can't figure out how to put the image and the text next to it
*/
//Bottom part
JPanel bottom = new JPanel();
JButton graph = new JButton("Graph");
JButton exit = new JButton("Exit");
bottom.add(graph);
bottom.add(exit);
container.add(bottom, BorderLayout.SOUTH);
this.setContentPane(container);
}
For most practical cases, you use multiple, nested containers, with a LayoutManager suited to the layout within each container.
Each LayoutManager does one specific job, in practice you often want differnt regions of a UI layouted in different ways. So for each region use a separate Container (e.g. JPanel) and set a LayoutManager that suits your layout requirements.
The big hurdle for beginners seems to be to get the point that LayoutManagers can (and often must) be used with nested containers.
Try using a JPanel
Create the JPanel
Place your JPanel into your JFrame
Position the labels, button, textfield onto the newly created JPanel.
It should do the trick. and it is pretty basic. You should be able to do the code on your own!

JTable Not Appearing

Whenever I set the panel's Layout to FlowLayout, the JTable appears, however my imageBackground and buttons are misplaced. And when I set the layout to null, the the table doesn't appear, but the buttons and imageBackground are where I wanted them to be. What am I'm going to do with this?
public class AssetPanel extends JPanel implements ActionListener{
private ArrayList<AssetDetails> assetList;
private Frame frame;
private Database db;
private JTable assetTable;
private JScrollPane scrollPane;
private JButton btnBack;
private JButton btnView;
public AssetPanel (Frame frame){
super();
this.frame = frame;
initialize();
}
public void initialize(){
setName("Assets");
setSize(700, 475);
setLayout(null);
setVisible(true);
db = new Database();
btnView = new JButton("View");
btnView.addActionListener(this);
btnView.setBounds(450, 400, 90, 20);
add(btnView);
btnBack = new JButton("Back");
btnBack.setFont(new Font("Tahoma", Font.BOLD, 12));
btnBack.setBounds(550, 400, 90, 20);
btnBack.addActionListener(this);
add(btnBack);
ImageIcon imageBackground = new ImageIcon(AssetPanel.class.getResource("/resources/assets.png"));
JLabel jlBackground = new JLabel(imageBackground);
jlBackground.setBounds(0,0, 700, 475);
add(jlBackground);
initializeTable();
}
#Override
public void actionPerformed(ActionEvent ae) {
if(ae.getSource() == btnBack){
frame.changePanel("Main Menu");
}
}
public void initializeTable(){
Object[][] assetData;
assetList = new ArrayList<>();
String[] columnNames = {"Asset Name", "Date Acquired", "Type", "Classification"};
assetList = db.getAssetTable();
assetData = new Object[assetList.size()][columnNames.length];
for(int i = 0; i < assetList.size(); i++){
assetData[i][0] = assetList.get(i).getAssetName();
assetData[i][1] = assetList.get(i).getDateAcquired();
assetData[i][2] = assetList.get(i).getType();
assetData[i][3] = assetList.get(i).getClassification();
}
assetTable = new JTable(assetData, columnNames);
assetTable.setPreferredScrollableViewportSize(new Dimension(400, 100));
assetTable.setLocation(150, 100);
assetTable.setFillsViewportHeight(true);
scrollPane = new JScrollPane(assetTable);
add(scrollPane);
}
}
Don't use a null layout or use the setBounds() method to position and size components.
however my imageBackground and buttons are misplaced
A background is a Container component. That is you create it as a component and paint an image as the background. Then you add other components to the background component. Now the image will appear in the background and the other components appear on top of it.
See the Background Panel to give an example of creating a background component.
On possible solution: I recommend switching to Mig Layout as a solution to all java layout problems. I now use it for the layout of every single container component in my apps. If you switch you'll probably be glad you did (will never again have problems like that listed in this question).
http://www.miglayout.com/
MigLayout may be included in the JDK in a future version of java.
null layouts mean you have to explicitly place all the components.
I recommend BoxLayout. it's really simple, and you can put in spacers to create space between objects, and glue to fill in all remaining space.
you can also nest the boxes, as well.
if you look at java sample code (and at the source for things);
they nest a lot of JPanels to get the complicated layouts.
Try adding this before trying the steps below if it does not work:
// Set your flow layout thus:
setLayout(new FlowLayout(FlowLayout.LEFT,5,5));
// Set your table Auto Resize Mode to OFF
assetTable.setAutoResizeMode(assetTable.AUTO_RESIZE_OFF);
EXTRA: Try if above tips does not help
Technically, your class should extend a JFrame.
Add a root layout to the class(i.e. the JFrame):
setLayout(new FlowLayout(FlowLayout.LEFT,5,5));
Create two panels; one should contain your label and buttons components.
The other should contain the JScrollPane that contains your table.
Both panels can have their Layout which determines how the components will be laid out.
You can use FlowLayout.
Then you can add both panels to the mother layout (JFrame).

Categories