This question already has an answer here:
Only one component shows up in JFrame
(1 answer)
Closed 6 years ago.
I created one JLabel as a heading and customised it, which displayed with no issue. The problem came when I attempted to create a second JLabel, as only the second JLabel would display. When I created a third one, only that would display but not the first and second.
Basically, only the latest JLabel is being displayed. How can I have multiple JLabel's displayed simultaneously.
Here is my code.
public class MainForm extends JFrame {
EmployeeDAO dao = new EmployeeDAO();
private static JLabel label, name;
MainForm()
{
super("Employee Database");
GUI();
}
private void GUI()
{
JLabel label = new JLabel("Enter Employee Information");
label.setVerticalAlignment(JLabel.TOP);
label.setHorizontalAlignment(JLabel.CENTER);
label.setFont(new Font("Serif", Font.PLAIN, 20));
label.setForeground(Color.red);
add(label);
JLabel name = new JLabel("Name: ");
add(name);
}
}
Usually, when you want to add more than one component to a container (as you're doing with the JLabels in the JFrame) you must decide which layout manager do you want to use so that components are displayed in the positions you want.
You should probably take a look at the tutorials related to laying out components in containers.
You will need to select a Layout Manager, and call setLayout accordingly.
Use .setBounds for each element you are adding to your scene, or use another layout such as grid layout to position your UI elements. The problem stems from when you add a new element, it goes on top of previous one.
Related
I'm trying to have painted into a JPanel (which is inside a ScrollPane), a bunch of labels and RadioButtons, dynamically. I receive an ArrayList with "Advice" objects, and I want to iterate over them to represent them in a way I have a label that describes them, and then, two radio buttons (to choose "Yes" or "No").
But at the moment, with this code at the JFrame's constructor, it's not properly working:
// My constructor
public CoachingFrame(AdvicesManager am) {
initComponents();
this.am = am;
// I set the layout for the inner panel (since ScrollPane doesn't allow BoxLayout)
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
// Iterate over the arraylist
for(int i=0;i<am.advices.size();i++){
//Add elements to the panel
panel.add(new JLabel( am.advices.get(i).getQuestion()));
ButtonGroup group = new ButtonGroup();
// Group the RadioButtons inside another panel, so I can use FlowLayout
JPanel buttonsPanel = new JPanel();
buttonsPanel.setLayout(new FlowLayout());
JRadioButton rad1 = new JRadioButton();
JRadioButton rad2 = new JRadioButton();
group.add(rad1);
group.add(rad2);
buttonsPanel.add(rad1);
buttonsPanel.add(rad2);
// Add the radiobuttons' panel to the main one, and revalidate
panel.add(buttonsPanel);
panel.revalidate();
}
// Finally, add the panel to the ScrollPane.
questions.add(panel);
}
I receive the arraylist correctly; I already checked that. The problem seems to be when painting the components.
Since I always use the NetBeans GUI creator, I'm not very used to add components via code. Can someone help me? I guess I'm missing something here.
edit: Note that "questions" is the ScrollPane object!
edit 2: This "questions" panel should have all those components painted: http://i.imgur.com/tXxROfn.png
As Kiheru said, ScrollPane doesn't allow views (like my JPanel) to be added with .add(), instead, I had to use .setViewportView(Component). Now it's working perfectly, thank you!
I am a newbie, I have a question. I am trying to use Eclipse to write a Java windows application, in which I will have a main window, which will contain several things, like a dashboard sort of thing, and it will have buttons, for example to add a record to a database, and this button when pressed, will open a new relevant window on top.
I tried to start, I wrote this code in Java, and for some reason, the button is in the size of the frame...full screen ! How do I fix it ?
Can you suggest me better ideas for a design than what I specified ?
Thank you
public class MainClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame jfrm = new JFrame("Frame1");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
jfrm.setSize(screenSize.width, screenSize.height);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel jlab = new JLabel("Hello");
jfrm.add(jlab);
JButton button = new JButton("Button");
button.setSize(new Dimension(50, 50));
button.setLocation(500, 350);
jfrm.getContentPane().add(button);
jfrm.setVisible(true);
}
Add a layout to the JFrame first. For example FlowLayout:
jfrm.setLayout(new FlowLayout());
"I tried to start, I wrote this code in Java, and for some reason, the button is in the size of the frame...full screen ! How do I fix it ?"
The reason the button stretches is because JFrame has a default BorderLayout that does not respect the preferred sizes of child components.
The solution is to set the Layout Manager to layout that does respect preferred sizes. The image blow from this example shows the most common Layout Managers and show visually which one respect the preferred size of child components.
Also, the BorderLayout is also the reason your JLabel does not show. By default, every component that is added to a BorderLayout without a position specified e.g. BorderLayout.SOUTH, will automatically be placed in the BorderLayout.CENTER position. Each position may only have one component. So when you add the JLabel it goes to the CENTER, but when you add the JButton, it also goes the CENTER, kicking out the JLabel.
If you've never encountered Layout Managers, this is probably all confusing to you. You should take the time to go over How to Layout Components Within a Container
You need to use some form of layoutmanager, you can use this information: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
You must use Layout manager.
Use this code..
public static void main(String[] args)
{
JFrame jfrm = new JFrame("Frame1");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
jfrm.setSize(screenSize.width, screenSize.height);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel jlab = new JLabel("Hello");
jfrm.add(jlab);
JButton button = new JButton("Button");
button.setSize(new Dimension(50, 50));
button.setLocation(500, 350);
jfrm.add(button);
jfrm.setVisible(true);
jfrm.setLayout(new FlowLayout());
jfrm.pack();
you forgot to add pack(). so use this code to get Jlabel and JButtion side by side.
Thanks...
I'm making a simple Jeopardy-esque game:
using Java Swing. It's obviously a JFrame with a JPanel in it and buttons in rows.
Now what I need is to add a layered panel with a centered and wrapped text in it:
Which I can remove later. I already tried using JTextPane and JTextArea and JPanel, none of those want to even display. The best effect I have achieved with AWT Panel, it does display but I can't center or wrap text in it.
Here's some code for which I appologise, I would usually try to make it short and readable but since it's not working I don't know what to do with it to make ti look better:
JLabel questionLabel = new JLabel(questionList.get(randomNumber).getQuestion(), SwingConstants.CENTER);
Font font = new Font("Arial", Font.PLAIN, 20);
//------------------JTextPane--------------------
JTextPane questionPane = new JTextPane();
questionPane.setForeground(Color.WHITE);
questionPane.setSize(gameWidth, gameHeight);
questionPane.setText(questionList.get(randomNumber).getQuestion());
questionPane.setFont(font);
questionPane.setEditable(false);
//------------------AWT panel--------------------
Panel awtPanel = new Panel();
awtPanel.setBackground(Color.blue);
awtPanel.setSize(game.getWidth(),game.getHeight());
Label labelQuestion = new Label("<html>" + questionList.get(randomNumber).getQuestion() + "</html>", Label.CENTER);
labelQuestion.setFont(font);
awtPanel.setForeground(Color.white);
awtPanel.add(labelQuestion);
//------------------JPanel-----------------------
JPanel layeredPanel = new JPanel();
layeredPanel.setBackground(Color.blue);
layeredPanel.setSize(game.getWidth(),game.getHeight());
JLabel jLabelQuestion = new JLabel("<html>" + questionList.get(randomNumber).getQuestion() + "</html>", SwingConstants.CENTER);
jLabelQuestion.setFont(font);
layeredPanel.setForeground(Color.WHITE);
layeredPanel.add(jLabelQuestion, BorderLayout.CENTER);
game.getLayeredPane().add(layeredPanel, JLayeredPane.DEFAULT_LAYER);
try {
Thread.sleep(3000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
button.setEnabled(false);
font = new Font("Arial", Font.PLAIN, 16);
button.add(jLabelQuestion, BorderLayout.CENTER);
button.setDisabledIcon(new ImageIcon(source.getScaledInstance(gameWidth/4, gameHeight/5, java.awt.Image.SCALE_SMOOTH)));
questionList.remove(randomNumber);
logger.info(questionList.size());
game.getLayeredPane().remove(layeredPanel);
UPDATE: I chnaged to SWT rather than Swing, and I use the StackLayout with a few Composites in it, and just change between them as I see fit.
You can generally solve issues like this with a JLabel.
I would recommend encapsulating the above grid in the BorderLayout.CENTER of another pane, perhaps a new content pane. Then, add the caption to BorderLayout.NORTH.
As a more tangible example,
private void createContent() {
this.getContentPane().setLayout(new BorderLayout());
//establish the panel currently set as center, here labeled "everythingElse"
this.getContentPane().add(everythingElse, BorderLayout.CENTER);
//Create a JLabel with your caption
JLabel jlbl = new JLabel("Question");
//format that caption, most details being rather obvious, but most importantly:
jlbl.setHorizontalAlignment(SwingConstants.CENTER); //keeps text centered
this.getContentPane().add(jlbl, BorderLayout.NORTH); //add it to the top of the panel
//...other cleanup operations...
}
The issue with grid panes is that they have a limited tolerance for the number of components visible in them. If you overload one, it won't show. For BorderLayout panes, you can easily swap new items into and out of them.
For efficiency's sake, I might recommend compiling this JLabel as a final somewhere else in your code, and holding onto it for when you need it. This way, you will also dodge overhead from repeatedly creating the label object.
Lastly, avoid AWT whenever you can. It's been deprecated for an excess of ten years, and if you do use it you will run into numerous critical problems involving heavyweight and lightweight component incompatibilities. If you intend to use another windowing kit, consider implementing the new standard, JavaFX, with a JFXPane-- it's much more tolerant of HTML syntax, as well.
I am trying to create a simple GUI that simulates a record store. I am still in the beginning stages.
I am running into trouble when I try to add text to describe what the user is expected to enter in the text field.
In addition, I am also having trouble positioning every textfield on its own line. In other words if there is space for two textfields in one line, then it displays in one line, and I am trying to display every text field on its own line.
This is what I tried so far:
item2 = new JTextField("sample text");
However the code above just adds default text within the text field, which is not what I need :/
I appreciate all the help in advance.
public class MyClass extends JFrame{
private JTextField item1;
private JTextField item2;
public MyClass(){
super("Matt's World of Music");
setLayout(new FlowLayout());
item1 = new JTextField();
item2 = new JTextField();
add(item1);
add(item2);
thehandler handler = new thehandler();
item1.addActionListener(handler);
item2.addActionListener(handler);
}
}
For your first problem, you need to use a JLabel to display your text. The constructor is like this:
JLabel label = new JLabel("Your text here");
Works really well in GUI.
As for getting things on their own lines, I recommend a GridLayout. Easy to use.
In your constructor, before adding anything, you do:
setLayout(new GridLayout(rows,columns,x_spacing,y_spacing));
x_spacing and y_spacing are both integers that determine the space between elements horizontally and vertically.
Then add like you have done. Fiddle around with it and you'll get it worked out.
So your final would look like:
setLayout(new GridLayout(2,2,10,10));
add(new JLabel("Text 1"));
add(text1);
add(new JLabel("text 2"));
add(text2);
You could just use a JLabel to label your textfields.
JLabel label1 = new JLabel("Item 1: ");
add(label1);
add(item1);
If you really want text inside the fields, you could set the text in the field with the constructor, and then add a MouseListener to clear the text on click:
item1 = new JTextField("Text");
item1.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (item1.getText().equals("Text")) // User has not entered text yet
item1.setText("");
}
});
Or, (probably better) use a FocusListener:
item1 = new JTextField("Text");
item1.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
if (item1.getText().equals("Text")) // User has not entered text yet
item1.setText("");
}
public void focusLost(FocusEvent e) {
if (item1.getText().equals("")) // User did not enter text
item1.setText("Text");
}
});
As for layout, to force a separate line, you use use a Box.
Box itemBox = Box.createVerticalBox();
itemBox.add(item1);
itemBox.add(item2);
add(itemBox);
Make:
item1 = new JTextField(10);
item2 = new JTextField(10);
that should solve problem with width of JTextField.
For beginning use GridLayout to display JTextField in one line. After that I strongly recomend using of MIG Layout http://www.migcalendar.com/miglayout/whitepaper.html.
put JLabel next to JTextField to describe what the user is expected to enter in the text field.
JLabel lbl = new JLabel("Description");
or you could also consider using of toolTipText:
item1.setToolTipText("This is description");
For making a form in Java Swing, I always recommend the FormLayout of JGoodies, which is designed to ... create forms. The links contains an example code snippet, which I just copy-pasted here to illustrate how easy it is:
public JComponent buildContent() {
FormLayout layout = new FormLayout(
"$label, $label-component-gap, [100dlu, pref]",
"p, $lg, p, $lg, p");
PanelBuilder builder = new PanelBuilder(layout);
builder.addLabel("&Title:", CC.xy(1, 1));
builder.add(titleField, CC.xy(3, 1));
builder.addLabel("&Author:", CC.xy(1, 3));
builder.add(auhtorField, CC.xy(3, 3));
builder.addLabel("&Price:", CC.xy(1, 5));
builder.add(priceField, CC.xy(3, 5));
return builder.getPanel();
}
Now for the description:
Use a label in front of the textfield to give a very short description
You can put a longer description in the textfield as suggested by #Alden. However, if the textfield is for short input, nobody will be able to read the description
You can use a tooltip (JComponent#setTooltipText) to put a longer description. Those tooltips also accept basic html which allows some formatting. Drawback of the tooltips is that the user of your application has to 'discover' that feature as there is no clear indication those are available
You can put a "help-icon" (like e.g. a question mark) after each text field (use a JButton with only an icon) where on click you show a dialog with a description (e.g. by using the JOptionPane class)
You can put one "help-icon" on each form which shows a dialog with a description for all fields.
Note for the dialog suggestion: I wouldn't make it a model one, allowing users to open the dialog and leave it open until they are finished filling in the form
How can I create an interface similar like the following in Java (tweetie)?
I was thinking of using a JTable with one columns and customized cell that has an image in it...not sure how to do it though.
If you are only going to have one column, than you can just use JList and it will be a little easier. But to answer your question, you need to create a cell renderer that can be used to represent the object in the list. The renderer would have a method (getListCellRendererComponent) which would return a Component that can be used to represent each item.
The simplest way (I would do it) would be to use a Vertical BoxLayout on a JPanel. Each tweet would then be its own JPanel (TweetPanel extends JPanel) with a BorderLayout where the image is on the WEST, and the tweet text is in the CENTER.
The following is how I would go about laying out one of the restaurant panels.
public ResturantPanel extends JPanel {
public ResturantPanel(String name, String address, List<String> reviews, Icon icon){
setLayout(new BorderLayout());
JLabel iconLabel = new JLabel(theIcon);
JLabel nameLabel = new JLabel(name);
JLabel addressLabel = new JLabel(address);
JPanel southReviewPanel = new JPanel();
southReviewPanel.setLayout(new BoxLayout(southReviewPanel, BoxLayout.Y_AXIS);
for (String review: reviews) {
southReviewPanel.add(new JTextArea(review));
}
add(southReviewPanel);
add(iconLabel, BorderLayout.West);
JPanel northPane = new JPanel();
northPane.setLayout(new BoxLayout(northPane, BoxLayout.Y_AXIS));
northPane.add(nameLabel);
northPane.add(addressLabel);
add(northPane, BorderLayout.North);
}
}
Note, this was written entirely in this editor window. It will have some typos. Also, you will have to play with the sizing of the icon, the text areas added to the southReviewPanel, and southReviewPanel to get everything how you want it to look.
You would then place a bunch of these on a JPanel in a JScrollPane, and you are good to go.