Java changing an existing component - java

I am trying to change a component from a JLabel to JComboBox when another option is added but for some reason the panel is not updating.
SSCCE:
public class SwitchComponent {
public static void main(String[] args) {
JPanel panel = new JPanel();
JComponent component = new JLabel("This is a test");
panel.add(component);
JComboBox<String> comboBox = new JComboBox<String>();
comboBox.addItem("Testing..");
comboBox.addItem("1.. 2.. 3..");
component = comboBox;
// I have tried with only one of the below lines and without any also...
// Doesn't seem to have an effect.
// I've also tried invoking the below methods on the panel instead.
component.revalidate();
component.repaint();
JOptionPane.showConfirmDialog(null, panel, "Test",
JOptionPane.OK_OPTION,
JOptionPane.PLAIN_MESSAGE);
}
}
Why is this happening? Shouldn't panel be referencing component such that any changes to component are reflected via panel?
Do I really have to completely reassemble the panel when the component changes?

When click YES/NO button on JOptionPane, JOptionPane will close.
We need to add the JComboBox to Panel again and use JOptionPane to show the Panel again in your code.
Have a try with this:
public class SwitchComponent {
public static void main(String[] args) {
JPanel panel = new JPanel();
JComponent component = new JLabel("This is a test");
panel.add(component);
JOptionPane.showConfirmDialog(null, panel, "Test",
JOptionPane.OK_OPTION,
JOptionPane.PLAIN_MESSAGE);
panel.remove(component);
JComboBox<String> comboBox = new JComboBox<String>();
comboBox.addItem("Testing..");
comboBox.addItem("1.. 2.. 3..");
panel.add(comboBox);
// I have tried with only one of the below lines and without any also...
// Doesn't seem to have an effect.
// I've also tried invoking the below methods on the panel instead.
panel.revalidate();
panel.repaint();
JOptionPane.showConfirmDialog(null, panel, "Test",
JOptionPane.OK_OPTION,
JOptionPane.PLAIN_MESSAGE);
}
}

I.e. the label could be second in a series of three, I would want the combo box to remain second when the component is changed to the combo box. Hence why I was trying to change the reference
Use a Card Layout. It will replace a component at the same location.

Related

JOptionPane.showConfirmDialog with a JScrollPane and a maximum size

I was trying to make a JFrame with a JScrollPane containing hundreds of JRadioButtons and two JButtons below (OK and Cancel). Finally I discovered the JOptionPane.showConfirmDialog(...) method.
It seems to be perfect for what I want : From a first JFrame, open a "window" with a Scroll containing my radio buttons and get the selected one in my first JFrame when I click on "OK".
However, when the showConfirmDialog appears, there is no JScrollPane, and we cannot see the bottom of the window (there are hundreds of radio buttons). So :
I tried to call JOptionPane.showConfirmDialog(myScrollPane) instead of adding the JScrollPane to a JPanel and call the method with a JPanel... it didn't work
I tried to initialize a JOptionPane object, then set its maximum size, then call the method showConfirmDialog with the initialized object but it doesn't work because "the method must be called in a static way".
So I need your help, here is my code, and I don't understand what is wrong and why I don't have a scroll with my radio buttons in the confirm dialog.
public void buildMambaJobPathWindow(ArrayList<String> list) {
ButtonGroup buttonGroup = new ButtonGroup();
JPanel radioPanel = new JPanel(new GridLayout(0,1));
for(int i=0; i<list.size(); i++) {
JRadioButton radioButton = new JRadioButton(list.get(i));
buttonGroup.add(radioButton);
radioButton.addActionListener(this);
radioButton.setActionCommand(list.get(i));
radioPanel.add(radioButton);
}
JScrollPane myScrollPane = new JScrollPane(radioPanel);
myScrollPane.setMaximumSize(new Dimension(600,600));
JOptionPane.showConfirmDialog(null, myScrollPane);
}
// Listens to the radio buttons
public void actionPerformed(ActionEvent e) {
String result = e.getActionCommand();
}
Thank you for your time.
As shown here, you can override the scroll pane's getPreferredSize() method to establish the desired size. If the content is larger in either dimension, the corresponding scroll bar will appear as needed.
JScrollPane myScrollPane = new JScrollPane(radioPanel){
#Override
public Dimension getPreferredSize() {
return new Dimension(600, 600);
}
};
JOptionPane.showConfirmDialog(null, myScrollPane);

How to edit a JComboBox with text selected in JEditorPane

I have a UI with two components - a JEditorPane and a JComboBox. My goal is to be able to type something into the JEditorPane, select a portion of the text, and while it is still selected type and/or select a value in an editable JComboBox.
This is for a text editor type of program where I want to change the font size of just the selected text in the editor pane. Where the font size is coming from the editable combo box. To clarify, I'm not asking how to apply styles to the text, I'm asking how to select a value in the combo box without losing the focus/selection in the JEditorPane.
Here's the code for the UI, but I wasn't sure where to begin doing anything with the focus...
public static void main(String [] args)
{
JFrame frame = new JFrame();
JPanel contentPane = new JPanel();
JComboBox<String> combo = new JComboBox(new String [] {"Hello", "World"});
contentPane.add(combo);
JEditorPane editor = new JEditorPane();
contentPane.add(editor);
frame.setContentPane(contentPane);
frame.pack();
frame.setVisible(true);
}
I'm asking how to select a value in the combo box without losing the focus/selection in the JEditorPane.
You don't lose the selection of the text in the editor pane when you select an item from the combo box. The selection remains, but it is just not painted until the editor pane regains focus.
So the easiest way to do this is to use a JMenuItem. Read the section from the Swing tutorial on Text Component Features for an example that does this.
If you still want to use the combo box then you can add Integer values to the combo box then the code in your ActionListener for the combo box would look something like:
#Override
public void actionPerformed(ActionEvent e)
{
Integer value = (Integer)comboBox.getSelectedItem();
Action action = new StyledEditorKit.FontSizeAction("Font size", value);
action.actionPerformed(null);
}
The StyledEditorKit actions extend from TextAction. The TextAction knows the last text component that had focus and therefore the font change is applied to that text component.
If you really want the text field to show the selection then you need to create a custom Caret and override the focusLost method to NOT invoke setSelectionVisible(false) (which is the default behaviour.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
public class DefaultCaretTest extends JFrame
{
public DefaultCaretTest()
{
JTextField textField1 = new JTextField("Text Field1 ");
JTextField textField2 = new JTextField("Text Field2 ");
textField1.setCaret(new SelectionCaret());
textField2.setCaret(new SelectionCaret());
textField1.select(5, 11);
textField2.select(5, 11);
((DefaultCaret)textField2.getCaret()).setSelectionVisible(true);
add(textField1, BorderLayout.WEST);
add(textField2, BorderLayout.EAST);
}
static class SelectionCaret extends DefaultCaret
{
public SelectionCaret()
{
setBlinkRate( UIManager.getInt("TextField.caretBlinkRate") );
}
public void focusGained(FocusEvent e)
{
setVisible(true);
setSelectionVisible(true);
}
public void focusLost(FocusEvent e)
{
setVisible(false);
}
}
public static void main(String[] args)
{
DefaultCaretTest frame = new DefaultCaretTest();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
Of course the selection will remain when focus is on any other component, not just the combo box.
You can also use:
comboBox.setFocusable(false);
Since the combo box can't gain focus the focus will remain on the text component, but the problem with this is that the user won't be able to use the keyboard to select a font size from the combo box. A proper GUI design always allows the user to use either the keyboard or the mouse to perform an action.

How to construct a JTextfield, and how to use the method selectAll()

I want to construct a Swing component JTextField, here is my Code
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JTextFieldGui{
JTextField textField;
JLabel labelInput;
JLabel labelOutput;
public static void main(String[] args) {
JTextFieldGui gui = new JTextFieldGui();
gui.go();
}
public void go(){
JFrame frame = new JFrame();
JPanel panelInput = new JPanel();
JPanel panelOutput = new JPanel();
labelInput = new JLabel("Your first name: ");
labelOutput = new JLabel("Enter your name, and you will see it here.");
textField = new JTextField(20);
JButton enter = new JButton("Enter");
JButton selectAll = new JButton("Select all text");
frame.setSize(300,200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panelInput.setLayout(new BoxLayout(panelInput, BoxLayout.X_AXIS));
textField.addActionListener(new LabelActionListener());
enter.addActionListener(new LabelActionListener());
selectAll.addActionListener(new TextFieldActionlistener());
frame.getContentPane().add(BorderLayout.NORTH, panelInput);
panelInput.add(labelInput);
panelInput.add(textField);
panelInput.add(enter);
panelInput.add(selectAll);
frame.getContentPane().add(BorderLayout.CENTER, panelOutput);
panelOutput.add(labelOutput);
}
class LabelActionListener implements ActionListener{
public void actionPerformed(ActionEvent event){
labelOutput.setText(textField.getText());
}
}
class TextFieldActionlistener implements ActionListener{
public void actionPerformed(ActionEvent event){
textField.selectAll();
}
}
}
Question1: I define the width of the text field in 20 columns, but it always take up a row, like image:
Question2: how to use the selectAll() method, I use it in a listener of the button selectAll, but when I click the button, nothing happens, why
I define the width of the text field in 20 columns, but it always take up a row,
This is the rule of a BoxLayout. A component is resized to fill the space available. A JTextField doesn't have a maximum size so it grows. The buttons and label do have a maximum size so they don't grow.
Don't use a BoxLayout, just use a FlowLayout. It will automatically leave space between each component which is a better layout.
I use it in a listener of the button selectAll, but when I click the button, nothing happens, why
Focus is still on the button. The selected text only displays when the text field has focus.
So in he listener code you need to add:
textField.requestFocusInWindow();
The following code is old:
frame.getContentPane().add(BorderLayout.NORTH, panelInput);
you don't need to get the content pane. You can just add the component to the frame.
the constraint should be the second parameter
there are new constraints to make the names more meaningful
So the code should be:
frame.add(panelInput, BorderLayout.PAGE_START, panelInput);
See the section from the Swing tutorial on How to Use BorderLayout for more information.

JTextField showing through JComboBox's dropdown after Scrolling

When a JTextField is in a JScrollPanel, if the panel has been scrolled, whenever the dropdown from a JComboBox is over the JTextField, the text field shows through the dropdown.
This only happens after the content has been scrolled (not on startup of the application).
The main question is how can we fix this?
Bonus points if the answer:
Is not a hack
Explains why is it happening in the first place
Things I've tried:
Moving the dropdown outside of the scrollpane (no change)
Adding a repaint to any and every container I could find on scroll (no change)
Different Layout managers for the content of the scrollpane (no change)
Code Example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TextFieldShowsThrough{
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createScrollDemo());
frame.pack();
// For demonstration purposes
frame.setSize(frame.getWidth() + 100, frame.getHeight() - 100);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static JScrollPane createScrollDemo(){
final Box optionsPanel = Box.createVerticalBox();
optionsPanel.add(createDropDown());
optionsPanel.add(createTextField("Option1"));
optionsPanel.add(createTextField("Option2"));
optionsPanel.add(createTextField("Option3"));
optionsPanel.add(createTextField("Option4"));
optionsPanel.add(createTextField("Option5"));
optionsPanel.add(Box.createVerticalGlue());
JScrollPane result = new JScrollPane(optionsPanel);
// Made attempts to fix here, but to no avail
/*result.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
#Override
public void adjustmentValueChanged(AdjustmentEvent e) {
result.repaint();
}
});*/
return result;
}
public static Box createDropDown(){
Box b = Box.createVerticalBox();
b.setAlignmentX(JLabel.LEFT_ALIGNMENT);
b.add(new JLabel("Language"));
JComboBox combo = new JComboBox(new String[]{"en", "fr", "es"});
combo.setMaximumSize(new Dimension(500, 25));
b.add(combo);
return b;
}
public static Box createTextField(String label){
Box mainBox = Box.createVerticalBox();
mainBox.setOpaque(true);
mainBox.setBackground(new Color((int)(Math.random() * 0x1000000))); // because fun
JLabel jLabel = new JLabel(label);
jLabel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
mainBox.add(jLabel);
Box secondaryBox = Box.createHorizontalBox();
secondaryBox.setAlignmentX(JLabel.LEFT_ALIGNMENT);
TextField tf = new TextField();
tf.setMaximumSize(new Dimension(500, 25));
secondaryBox.add(tf);
mainBox.add(secondaryBox);
return mainBox;
}
}
That's because you're using a java.awt.TextField, which is heavy weight component, inside a light weight container. The popup window used by the JComboBox can also be a light weight component.
AWT components don't play well with Swing components, they have z-ordering issues.
Change TextField tf = new TextField(); to JTextField tf = new JTextField();
You should also avoid using setPreferred/Minimum/MaximumSize (see Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? for more details) and instead use layout constraints and sizing hints (like the columns property of the JTextField)

Text not displayed when mouse is rolled over JLabel

With NetBeans (Java), I am having problems in JLabel. I have assigned an image as the icon of that JLabel.
Problem - 1st:
I want to display some text (e.g - logout) below that icon (image). How to do this?
Problem - 2nd:
I want to display some text when mouse is rolled over that JLabel. What should I do?
So , please guys tell me how to these things by writing code.
I recommend reading the basic Oracle tutorials which describe in detail how to accomplish this. You can use a MouseMotionListener to determine when the mouse is rolled over the JLabel, and you can position the JLabel text underneath the Icon of the JLabel by setting its vertical text position as described in the JLabel Tutorial. This should have all been found with a simple internet search of your questions, something that your question suggests was not done (and should have been) before asking
1.
Create a JPanel that contains two JLabels. This way you can control the layout of the internal components.
I used BoxLayout with the parameter BoxLayout.Y_AXIS to get the label below the icon.
2.
Add a MouseListener using the method component.addMouseListener(new MouseAdapter() { ... });, you'll need to create a MouseAdapter and implement any methods you need (click here).
Here is a working example for you buddy... Adapt this however you need to.
Note: You'll need to change the file-path of the ImageIcon()
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel container = new JPanel();
JPanel iconLabelPanel = new JPanel();
String TEXT_FIELD_TEXT = "Hover over the logout label.";
JLabel icon = new JLabel(new ImageIcon("C:\\Users\\Gary\\Google Drive\\Pictures\\puush\\ss (2015-02-19 at 06.00.00).png"));
JLabel label = new JLabel("Logout!");
JTextField textField = new JTextField(TEXT_FIELD_TEXT);
//Add a mouse motion listener for the JLabel
label.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
//Set text of another component
textField.setText("You're over Logout!");
}
#Override
public void mouseExited(MouseEvent e) {
//Set text of another component
textField.setText(TEXT_FIELD_TEXT);
}
});
//Add components and set parameters for iconLabelPanel
iconLabelPanel.setLayout(new BoxLayout(iconLabelPanel, BoxLayout.PAGE_AXIS));
iconLabelPanel.add(icon);
iconLabelPanel.add(label);
//Add components and set parameters for container
container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS));
container.add(iconLabelPanel);
container.add(textField);
//Set parameters for frame
frame.add(container);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(400, 400);
frame.setVisible(true);
}

Categories