I'm working on a program in which I'd used a JTextArea, JButton, JLabel and JPanel.
The logic I'd to implement is: user types a text in the given textArea and then click on the button. On button click I'd to retrieve the text from the textArea and create a label with the written text(as in textArea) and show it on the panel.
Everything I'd done previously is correct but the problem is with the label and panel. The label is not visible on the panel.
The code snippets is:
import java.awt.BorderLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.BevelBorder;
/**
*
* #author mohammadfaisal
* http://ermohammadfaisal.blogspot.com
* http://facebook.com/m.faisal6621
*
*/
public class CodeMagnets extends JFrame{
private JTextArea area4Label;
private JLabel codeLabel;
private JButton createButton;
private JPanel magnet;
public CodeMagnets(String title) throws HeadlessException {
super(title);
magnet=new JPanel(null);
JScrollPane magnetScroller=new JScrollPane(magnet);
magnetScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
magnetScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
add(BorderLayout.CENTER, magnetScroller);
JPanel inputPanel=new JPanel();
area4Label=new JTextArea(5, 30);
area4Label.setTabSize(4);
JScrollPane textScroller=new JScrollPane(area4Label);
inputPanel.add(textScroller);
createButton=new JButton("Create code magnet");
createButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//codeLabel=new JLabel(area4Label.getText());
codeLabel=new MyLabel(area4Label.getText());//this is for my new question
codeLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
codeLabel.setLocation(50, 20);
codeLabel.setVisible(true);
magnet.add(codeLabel);
area4Label.setText("");
//pack();
}
});
inputPanel.add(createButton);
add(BorderLayout.SOUTH, inputPanel);
//pack();
setSize(640, 480);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new CodeMagnets("Code Magnets");
}
}
You need to repaint()/validate() your panle after adding new components in it dynamically. So after this:
magnet.add(codeLabel);
add this:
magnet.validate();
or
magnet.repaint();
Also one thing you are using null layout for magnet panel. So must have to setBounds() of jLable before adding it to magnet panel. So it becomes
public void actionPerformed(ActionEvent e) {
codeLabel=new JLabel(area4Label.getText());
codeLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
codeLabel.setBounds(50, 20, 100, 100);
magnet.add(codeLabel);
magnet.repaint();
area4Label.setText("");
}
It is not recommended to use null as layout, you should use proper layout like BorderLayout or GridLayout or even simpler FlowLayout based on your requirement.
As said by #Andrew use something like:
codeLabel.setSize(codeLabel.getPreferredSize());
codeLabel.setLocation(50, 20);
instead of
codeLabel.setBounds(50, 20, 100, 100);
This will solve the size issue of jLabel.
public void actionPerformed(ActionEvent e) {
codeLabel=new JLabel(area4Label.getText());
codeLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
codeLabel.setBounds(50, 20, 100, 100);
codeLabel.setOpaque(True);
magnet.add(codeLabel);
magnet.repaint();
area4Label.setText("");
}
Related
I want to add a JPanel to a JLayeredPane when the user clicks enter, but the JPanel is not showing up.
If i add the JPanel to the JLayeredPane in the JFrame's constructor, everything is working correctly.
What do i have to do, that the JPanel is showing up, when the user clicks 'enter'?
Here's the code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Test extends javax.swing.JFrame {
public static void main(String[] args) {
Test test = new Test();
test.setSize(800, 500);
test.setVisible(true);
}
public Test() {
setLayout(new BorderLayout());
//LayeredPane on JFrame
JLayeredPane jlp = new JLayeredPane();
jlp.setLayout(new BorderLayout());
this.add(jlp, BorderLayout.CENTER);
//Adds a JPanel to the North
JPanel jPNorth = new JPanel();
jPNorth.setBackground(Color.RED);
jlp.add(jPNorth, BorderLayout.NORTH, JLayeredPane.DEFAULT_LAYER);
//Adds Enter Keybinding
InputMap key_input_map = jlp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap key_action_map = jlp.getActionMap();
key_input_map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "add_jpanel");
key_action_map.put("add_jpanel", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
JPanel jPSouth = new JPanel();
jPSouth.setBackground(Color.YELLOW);
jlp.add(jPSouth, BorderLayout.SOUTH, JLayeredPane.DEFAULT_LAYER);
System.out.println("enter");
}
});
}
}
Thanks,
Jumagoro
You did everything correct, the solution is very simple. When you dynamically add swing Components to each other, you must to use component.repaint(); and component.revalidate(); to redraw the elements. Add the two commands after everything is added. So your actionPerformed method should be changed to the following:
public void actionPerformed(ActionEvent e) {
JPanel jPSouth = new JPanel();
jPSouth.setBackground(Color.YELLOW);
jlp.add(jPSouth, BorderLayout.SOUTH, JLayeredPane.DEFAULT_LAYER);
//Need these to here!
jlp.repaint();
jlp.revalidate();
System.out.println("enter");
}
enter image description here
How can I make it like that?
1) If user opens that program, you don't have to click on textfield to receive focus, instead, if you switch to that program, it immediatetly gives you a focus to write instead of clicking for focus.
2) If user writes a ID number or item name to textfield, textarea responds to textfield and shows that ID or name to the user, like, pops up.
3) How to make textarea smaller in case, that even panel shows out in corners? I'd like to make a textarea a little bit smaller like a box and outside a box, its just a gray color.
In order to fully help me, I'll gladly give out the code.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
public abstract class Itemlist extends JFrame implements ActionListener, FocusListener {
/**
*
*/
private static final long serialVersionUID = 1L;
public static void main(String args[]) {
// create JFrame
JFrame frame = new JFrame("small project");
frame.setDefaultCloseOperation(2);
frame.setPreferredSize(new Dimension(400, 600));
frame.setLayout(new BorderLayout());
frame.setResizable(false);
JPanel panel = new JPanel(new FlowLayout(SwingConstants.LEADING, 10, 10));
frame.add(panel);
panel.setPreferredSize(new Dimension(100, 50));
JTextField tf = new JTextField(25);
tf.setPreferredSize(new Dimension(100, 35));
Font f = new Font("Times New Roman", Font.BOLD, 18);
tf.setFont(f);
panel.add(tf);
frame.add(tf, BorderLayout.PAGE_END);
tf.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
tf.getText();
}
#Override
public void focusLost(FocusEvent e) {
tf.setText("");
}
});
JTextArea ta = new JTextArea();
frame.add(ta);
Font font = new Font("Times New Roman", Font.PLAIN, 16);
ta.setEditable(false);
ta.setFont(font);
JScrollPane scrollPane = new JScrollPane(ta);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
frame.add(scrollPane);
BufferedReader br;
String contents;
try {
br = new BufferedReader(new FileReader("C:/ItemList.txt"));
contents = br.readLine();
while ((contents = br.readLine()) != null) {
ta.read(br, null);
}
br.close();
} catch (IOException e) {
}
frame.pack();
// frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent arg0) {
}
}
*All help is appreciated. Have been stuck on it.
I suspect you want to consider using a WindowListener and monitor for the windowActivated event, at which time you can call requestFocusInWindow on the JTextField to transfer focus to it automatically. Focus management is a little bit of a black art, as it tends to work slightly differently on different platforms
I'm not sure entirely what you mean, but I'd look at the ActionListener support. This will require the user to hit the "action" key (typically Enter) to trigger it. If you want real time feedback, the a DocumentListener would be what you're looking for
Make use of the JTextAreas constructor to specify the preferred number of rows and columns. This will define the preferred scrollable size of the component, which will effect the size of the JScrollPane as well
In future, try and constrain you question to single, focused question, they are easier to answer and generally produce more detail
If I have a JLabel with <u> tag, such as <html><u>text</u>, with WindowsLookAndFeel and WindowsClassicLookAndFeel the underline is not rendered. I have reported this bug.
If no Look and Feel is set, or with Nimbus, all correct.
I know I can set the font attributes of the JLabel, but what if I only want to render one part of the text?
EDIT: I have tested and found that it is a bug of MigLayout combined with UIManger font setting.
Try the code: comment out anyone of UIManager.put("Label.font") or setLayout(MigLayout(xxx)) will solve the problem, but if they are both present, the line is not shown. I changed the title of question to describe it better. Now I see it has nothing to do with L&F, because Nimbus neither render the line.
The effect is:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel;
import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
import net.miginfocom.swing.MigLayout;
public class WindowsLFUnderline extends JDialog {
public WindowsLFUnderline() {
begin();
}
private void begin() {
try {
UIManager.setLookAndFeel(new WindowsClassicLookAndFeel());
//UIManager.setLookAndFeel(new WindowsLookAndFeel());
UIManager.put("Label.font", new Font("SimSun", Font.PLAIN, 13));
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new BorderLayout());
JTabbedPane tabs = new JTabbedPane();
JLayeredPane layer = new JLayeredPane();
layer.setLayout(new MigLayout("insets 5, fill", "[]", "[]"));
// layer.setLayout(new BorderLayout());
JLabel test = new JLabel("<html><u>TEST</u>");
test.setForeground(Color.BLUE);
test.setBounds(0, 0, 300, 150);
layer.add(test, BorderLayout.CENTER);
tabs.addTab("tab1", layer);
add(tabs, BorderLayout.CENTER);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
WindowsLFUnderline frame = new WindowsLFUnderline();
}
});
}
}
The search bar is 'search_bar', I'm trying to move it to the left hand side of the box with 'j_panel.add(search_bar, BorderLayout.WEST);' but it doesn't move from the middle. Any ideas on how to do this? Thanks
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
public class Main {
public static void main(String args[]) {
JFrame jfrm = new JFrame("Test");
jfrm.setSize(1024, 600);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrm.setResizable(false);
JTextField search_bar = new JTextField("Search...", 25);
search_bar.setPreferredSize(new Dimension(1,35));
JTextArea body = new JTextArea(32,83);
body.setPreferredSize(new Dimension());
body.setEditable(false);
JButton search_button = new JButton("Search");
JPanel j_panel = new JPanel();
j_panel.setLayout(new FlowLayout());
j_panel.add(search_bar, BorderLayout.WEST);
j_panel.add(search_button, null);
j_panel.add(body, BorderLayout.EAST);
j_panel.setBackground(Color.gray);
search_button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
final String text = search_bar.getText();
body.setText(text);
}
});
jfrm.setContentPane(j_panel);
jfrm.setVisible(true);
}
}
j_panel.setLayout(new FlowLayout());
j_panel.add(search_bar, BorderLayout.WEST);
BorderLayout.WEST is not applicable for FlowLayout. If you want to use a BorderLayout, use one instead of FlowLayout.
You cannot position components exactly the way you'd like when using FlowLayout.
By using BorderLayout you are bound to have only 5 components, because BorderLayout can handle 5 components max.
My question is about layout in Java Swing.
I want to make a screen like shown below. I saw this video on youtube and made a gif of the part I want.
I want 2 panels and a button like this:
When i clicked the button the JPanel will be hidden and JTable's width will be 100% like html/css like this; (And when button clicked again JPanel will be shown etc..)
How can I do this? Which layout should I use?
There is more than one way to do it, but here's an example that uses BorderLayout as the main layout, and places the button in a left aligning FlowLayout:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
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.SwingConstants;
import javax.swing.SwingUtilities;
public class LayoutDemo {
private LayoutDemo() {
JFrame frame = new JFrame("Demo");
frame.setLocationByPlatform(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel buttonHolder = new JPanel(new FlowLayout(FlowLayout.LEADING));
frame.add(buttonHolder, BorderLayout.NORTH);
JButton button = new JButton("Toggle visibility");
buttonHolder.add(button);
final JPanel left = new JPanel();
left.setPreferredSize(new Dimension(100, 200));
left.setBackground(Color.BLUE);
frame.add(left, BorderLayout.LINE_START);
JLabel table = new JLabel("This pretends to be a table", SwingConstants.CENTER);
table.setPreferredSize(new Dimension(400, 200));
frame.add(table);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
left.setVisible(!left.isVisible());
}
});
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new LayoutDemo();
}
});
}
}
I used setPreferredSize() to give the components some reasonable default size, but usually it should be automatically calculated by the layout manager from the sizes of the child components, or in case of a custom component, you should override getPreferredSize() return what is appropriate for the component.
The result looks like: