Why is control TAB keystroke not working? - java

Following is my code
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.util.Arrays;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Test {
private int selected = 0;
public Test() {
JLabel[] lables = new JLabel[] { new JLabel("Lable1"),
new JLabel("Label2") };
JFrame frame = new JFrame("FrameDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = (JPanel) frame.getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(lables[0]);
contentPane.add(lables[1]);
frame.pack();
contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke("control TAB"), "next");
Action action = new AbstractAction("next") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
selected++;
Arrays.stream(lables).forEach(
l -> l.setForeground(Color.LIGHT_GRAY));
lables[selected % 2].setForeground(Color.BLACK);
System.out.println(selected);
contentPane.revalidate();
contentPane.repaint();
}
};
contentPane.getActionMap().put("next", action);
frame.setVisible(true);
}
public static void main(String[] args) {
new Test();
}
}
But when I press control TAB, nothing happens. But when if I change the code to something like KeyStroke.getKeyStroke("control K"), "next"); the control K keystorke changes the foreground color.
What am I doing wrong? Is the "control Tab" reserved for some purpose? If so, how can I change that behaviour so that I can bind that keystroke to my action?

Related

how to change the background color in a window application in java

I want to create an application where pressing a button changes the background color, but I don't know why the color won't change. I can't change it at all. Swapping the button color and its font works, but I can't change the background color.
package okno;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
public class Kolory extends JFrame implements ActionListener {
static JButton FirstButton;
Color [] colors= {Color.GREEN,Color.RED,Color.BLACK};
JLayeredPane screen;
public Kolory() {
super("Zmiana kolorów");
screen = new JLayeredPane();
getContentPane().add(screen).setBackground(Color.RED);;
screen.setPreferredSize(new Dimension(500,500));
FirstButton = new JButton("Pierwszy przycisk");
screen.add(FirstButton);
FirstButton.setBounds(30, 30, 150, 20);
FirstButton.addActionListener(this);
}
public static void main(String[] args) {
JFrame frame = new Kolory();
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.pack();
}
#Override
public void actionPerformed(ActionEvent e) {
Random r = new Random();
int counter = r.nextInt(3);
screen.setBackground(colors[counter]);
}
}

Java selectable JLabel

I have made a GUI with a gallery panel which shows images held in JLabels. I need to make JLabel highlightable and then remove it if the user clicks remove. Is there a way or should I change my approach?
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
public class GalleryPanel extends JPanel
{
private static final long serialVersionUID = 1L;
private int currentImage;
private JLabel[] images;
private final int MAX_IMAGES = 12;
private JScrollPane scrollPane;
private JList<JLabel> imageGallery;
private DefaultListModel<JLabel> listModel;
private JPanel imageHolder;
public void init()
{
setLayout(new BorderLayout());
imageHolder = new JPanel();
imageHolder.setLayout(new BoxLayout(imageHolder, BoxLayout.PAGE_AXIS));
imageHolder.setSize(getWidth(), getHeight());
images = new JLabel[MAX_IMAGES];
listModel = new DefaultListModel<JLabel>();
listModel.addElement(new JLabel(new ImageIcon("Untitled.png")));
imageGallery = new JList<JLabel>(listModel);
imageGallery.setBackground(Color.GRAY);
imageGallery.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
imageGallery.setLayoutOrientation(JList.VERTICAL);
imageGallery.setFixedCellHeight(50);
imageGallery.setFixedCellWidth(100);
scrollPane = new JScrollPane(imageHolder);
scrollPane.setBackground(Color.RED);
add(scrollPane, BorderLayout.CENTER);
}
public void addImageToGallery(File file)
{
if ( currentImage <= images.length - 1)
{
BufferedImage bufImage = null;
try
{
bufImage = ImageIO.read(file); //tries to load the image
}
catch (Exception e)
{
System.out.println("Unable to load file " + file.toString());
}
Image resizedImage = bufImage.getScaledInstance(bufImage.getWidth()/5, bufImage.getHeight()/5, Image.SCALE_SMOOTH);
ImageIcon icon = new ImageIcon(resizedImage);
images[currentImage] = new JLabel(icon, JLabel.CENTER);
//images[currentImage].setSize(resized);
//images[currentImage
images[currentImage].setBorder(new TitledBorder(new LineBorder(Color.GRAY,5), file.toString()));
imageHolder.add(images[currentImage]);
revalidate();
repaint();
currentImage++;
}
else
{
throw new ArrayIndexOutOfBoundsException("The gallery is full");
}
}
public final int getMaxImages()
{
return MAX_IMAGES;
}
public Dimension getPreferredSize()
{
return new Dimension(300, 700);
}
}
So you first of call should be the tutorals
How to use Lists
Selecting items in a list
Adding items to and removing items from a list
Which will give you the basic information you need to proceeded.
Based on your available code, you should not be adding a JLabel to the ListModel, you should never add components to data models, as more often than not, Swing components have there own concept of how they will render them.
In your case, you're actually lucky, as the default ListCellRenderer is based on a JLabel and will render Icon's automatically, for example
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
DefaultListModel model = new DefaultListModel();
model.addElement(new ImageIcon("mt01.jpg"));
model.addElement(new ImageIcon("mt02.jpg"));
model.addElement(new ImageIcon("mt03.jpg"));
JList list = new JList(model);
list.setVisibleRowCount(3);
list.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
System.out.println(list.getSelectedIndex());
}
}
});
JFrame frame = new JFrame("Test");
frame.add(new JScrollPane(list));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}

How can we put value on text field on output screen?

I want to put value in txtf1 at output screen and get it. How can we put value on text field on output screen?
import java.awt.Color;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public class demog extends JPanel implements ActionListener{
private TextField textf, txtf1;
public void jhand(){
textf = new TextField();
textf.setSize(40, 40);
textf.setText("20");
textf.setEditable(false);
textf.setBackground(Color.WHITE);
textf.setForeground(Color.BLACK);
//textf.setHorizontalAlignment(SwingConstants.CENTER);
textf.setLocation(15, 15);
//textf.addActionListener(this);
txtf1 = new TextField();
txtf1.setSize(40, 40);
txtf1.getText();
txtf1.setEditable(false);
txtf1.setBackground(Color.WHITE);
txtf1.setForeground(Color.BLACK);
//txtf1.setHorizontalAlignment(SwingConstants.CENTER);
txtf1.setLocation(50, 50);
JFrame frame = new JFrame("demo");
JPanel p = new JPanel();
p.setOpaque(true);
p.setBackground(Color.WHITE);
p.setLayout(null);
frame.setContentPane(p);
frame.setSize(500,500);
frame.setVisible(true);
p.add(textf);
p.add(txtf1);
}
public void actionPerformed(ActionEvent evt) {
String text = textf.getText();
System.out.println(text);
}
public static void main(String... args){
demog g = new demog();
g.jhand();
}
}
You have to change some of your code in order to work. You had some problem in your code which I resolved them for you in the following code. See the comments to learn some in swing ;-)
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.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
// Use upper Case in the start of you class names:
public class Demog extends JPanel implements ActionListener {
private JTextField textf, txtf1;
public Demog() {
jhand();
}
public void jhand() {
setLayout(new FlowLayout()); // Always set the layout before you add components
// you can use null layout, but you have to use setBounds() method
// for placing the components. For an advanced layout see the
// tutorials for GridBagLayout and mixing layouts with each other.
textf = new JTextField(); // Do not mix AWT component with
// Swing (J components. See the packages)
//textf.setSize(40, 40); // Use setPreferredSize instead
textf.setPreferredSize(new Dimension(40, 40));
textf.setText("20");
textf.setEditable(false); // Text fields are for getting data from user
// If you need to show something to user
// use JLabel instead.
textf.setBackground(Color.WHITE);
textf.setForeground(Color.BLACK);
add(textf);
txtf1 = new JTextField();
//txtf1.setSize(40, 40); Use setPreferredSize instead
txtf1.setPreferredSize(new Dimension(40, 40));
txtf1.getText();
txtf1.setEditable(false);
txtf1.setBackground(Color.WHITE);
txtf1.setForeground(Color.BLACK);
add(txtf1);
JButton b = new JButton("Click ME!");
b.addActionListener(this);
add(b);
}
public void actionPerformed(ActionEvent evt) {
String text = textf.getText();
JOptionPane.showMessageDialog(Demog.this, "\"textf\" text is: "+text);
}
public static void main(String[] args) {
JFrame frame = new JFrame("demo");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Demog p = new Demog();
p.setBackground(Color.WHITE);
frame.setContentPane(p);
frame.setSize(500, 500);
frame.setVisible(true);
}
}
Good Luck.

JButton & Action & KeyBinding

I have created a JButton class that recieving Action, the JButton class includes keystrokes & mouse listener so i can use the same class in multiple frames as needed.
My problems is that:
JButton not getting the focus when pressing the key, but it doing the action.
i need to make a new background or something that tell the user that the button did the action.
Any ideas??
Here is my code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import swtdesigner.SwingResourceManager;
public class IButtonSave extends JButton{
private static final long serialVersionUID = 1L;
private Action action = null;
public IButtonSave() {
super();
setFocusPainted(true);
setFocusable(true);
try {
jbInit();
} catch (Throwable e) {
e.printStackTrace();
}
}
private void jbInit() throws Exception {
setMargin(new Insets(0, 0, 0, 0));
setBorder(new LineBorder(Color.black, 1, true));
setIconTextGap(0);
setHorizontalTextPosition(SwingConstants.CENTER);
setVerticalTextPosition(SwingConstants.TOP);
setPreferredSize(new Dimension(50, 43));
setMinimumSize(new Dimension(50, 43));
setMaximumSize(new Dimension(50, 43));
addMouseListener(new ThisMouseListener());
setVerifyInputWhenFocusTarget(true);
}
public void setAction(Action a){
action = a;
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_F1,0,true);
KeyStroke ks2 = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0);
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, "Save");
getInputMap(JComponent.WHEN_FOCUSED).put(ks2, "Save");
getActionMap().put("Save", a);
setText("Save [F1]");
setIcon(SwingResourceManager.getIcon(SwingResourceManager.class, "/images/small/save.png"));
setToolTipText("[F1]");
}
private class ThisMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
this_mouseClicked(e);
}
}
protected void this_mouseClicked(MouseEvent e) {
if(e.getClickCount() >= 1){
action.actionPerformed(null);
}
}
}
Why extend JButton class when you can simply add KeyBindings to its instance?
Not to sure what you want but this works fine for me:
Basically a JButton which can be activated by mouse click, or pressing F1 (as long as focus is in window and if pressed will shift focus to JButton) or ENTER (only when in focus of JButton).
When the AbstractAction is called it will call requestFocusInWindow() on JButton (thus pressing F1 will make button gain focus which is what I think you wanted):
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JButton btn = new JButton("Button");
AbstractAction aa = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
System.out.println("Here");
btn.requestFocusInWindow();//request that the button has focus
}
};
//so button can be pressed using F1 and ENTER
btn.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "Enter");
btn.getActionMap().put("Enter", aa);
btn.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0), "F1");
btn.getActionMap().put("F1", aa);
btn.addActionListener(aa);//so button can be clicked
JTextField tf = new JTextField("added to show ENTER wont work unless button in focus");
frame.add(tf);
frame.add(btn, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
});
}
}
UPADTE:
alternatively as #GuillaumePolet suggested (+1 to him) override processKeyBinding of JButton and check for appropriate key and than call the method:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JButton btn = new JButton("Button") {
#Override
protected boolean processKeyBinding(KeyStroke ks, KeyEvent ke, int i, boolean bln) {
boolean b = super.processKeyBinding(ks, ke, i, bln);
if (b && ks.getKeyCode() == KeyEvent.VK_F1) {
requestFocusInWindow();
}
return b;
}
};
AbstractAction aa = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
System.out.println("Here");
}
};
//so button can be pressed using F1 and ENTER
btn.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "Enter");
btn.getActionMap().put("Enter", aa);
btn.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0), "F1");
btn.getActionMap().put("F1", aa);
btn.addActionListener(aa);//so button can be clicked
JTextField tf = new JTextField("added to show ENTER wont work unless button in focus");
frame.add(tf);
frame.add(btn, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
});
}
}
Not sure this is the best way to do it, but it works decently enough and if it is not the best way, you get a free SSCCE out of this answer.
I override processKeyBindings() and if it returns true then I grab the focus to indicate that the action has been performed. If you want to do something else you just need to modify the code there.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class IButtonSave extends JButton {
private static final long serialVersionUID = 1L;
public IButtonSave() {
super();
setFocusPainted(true);
setFocusable(true);
}
#Override
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
boolean processKeyBinding = super.processKeyBinding(ks, e, condition, pressed);
if (processKeyBinding) {
requestFocusInWindow();
}
return processKeyBinding;
}
#Override
public void setAction(Action a) {
super.setAction(a);
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0, true);
KeyStroke ks2 = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, "Save");
getInputMap(JComponent.WHEN_FOCUSED).put(ks2, "Save");
getActionMap().put("Save", a);
setText("Save [F1]");
setToolTipText("[F1]");
}
protected void initUI() {
JFrame frame = new JFrame(IButtonSave.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextArea textarea = new JTextArea(5, 30);
JPanel buttonPanel = new JPanel();
AbstractAction someAction = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
System.err.println("Action performed");
}
};
IButtonSave button = new IButtonSave();
button.setAction(someAction);
buttonPanel.add(button);
frame.add(new JScrollPane(textarea));
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new IButtonSave().initUI();
}
});
}
}

Look and feel is not updating in Swing JTabbedPane

I have created an application in Java Swing. I offer the option to change the look and feel of the application from a menu, but after adding a new tab in JTabbedPane, it is not getting updated with the new look and feel.
I have already used this code:
Window windows[] = Frame.getWindows();
for(Window window : windows) {
SwingUtilities.updateComponentTreeUI(window);
}
Leveraging #Andrew's example and this old thing, it seems to work for me.
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
/**
* #see https://stackoverflow.com/a/11949899/230513
* #see https://stackoverflow.com/a/5773956/230513
*/
public class JTabbedText {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
private final JTabbedPane jtp = new JTabbedPane();
#Override
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jtp.addTab("Model", createPanel());
jtp.addTab("View", createPanel());
jtp.addTab("Control", createPanel());
f.add(createToolBar(f), BorderLayout.NORTH);
f.add(jtp, BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
private static JToolBar createToolBar(final Component parent) {
final UIManager.LookAndFeelInfo[] available =
UIManager.getInstalledLookAndFeels();
List<String> names = new ArrayList<String>();
for (LookAndFeelInfo info : available) {
names.add(info.getName());
}
final JComboBox combo = new JComboBox(names.toArray());
String current = UIManager.getLookAndFeel().getName();
combo.setSelectedItem(current);
combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
int index = combo.getSelectedIndex();
try {
UIManager.setLookAndFeel(
available[index].getClassName());
SwingUtilities.updateComponentTreeUI(parent);
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
});
JToolBar bar = new JToolBar("L&F");
bar.add(combo);
return bar;
}
private static Box createPanel() {
Box panel = new Box(BoxLayout.X_AXIS);
JLabel label = new JLabel("Code: ", JLabel.LEFT);
label.setAlignmentY(JLabel.TOP_ALIGNMENT);
JTextArea text = new JTextArea(4, 16);
text.setAlignmentY(JTextField.TOP_ALIGNMENT);
text.append("#" + panel.hashCode());
text.append("\n#" + label.hashCode());
text.append("\n#" + label.hashCode());
panel.add(label);
panel.add(text);
return panel;
}
}

Categories