I have a small text editor that I made in Java Swing with JTextArea.
I want to implement the following:
When the user presses Command+Backspace I want to remove all the text from the beginning of the line up to the cursor. How to implement this? I tried using KeyListeners but it doesn't work.
For example (before user presses Command+Backspace) ...
Result (after user presses Command+Backspace) ...
My code (Not 100% exact compared to the image):
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Main{
static JFrame frame = new JFrame();
static JTextArea textArea = new JTextArea();
static JScrollPane scrollPane = new JScrollPane(textArea);
public static void main(String[] args) throws BadLocationException {
frame.setTitle("Untitled");
addComponentsToFrame();
textArea.addKeyListener(new KeyListener(){
#Override
public void keyTyped(KeyEvent e) {
if(e.getKeyCode() == (Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() | KeyEvent.VK_BACK_SPACE)){
System.out.println("Delete"); //Placeholder
}
}
#Override
public void keyPressed(KeyEvent e) {}
#Override
public void keyReleased(KeyEvent e) {}
});
}
public static void addComponentsToFrame(){
scrollPane.setAutoscrolls(true);
frame.add(scrollPane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
For now when I have placed a print Statement as a place holder, since I don't know how to delete all the words from the beginning of the line up to the cursor (i.e. the logic).
Credits: #Abra
Solution:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.text.BadLocationException;
import java.awt.Toolkit;
public class TestSamplePrograms {
private JTextArea textarea;
private void buildAndShowGui() {
JFrame frame = new JFrame("Untitled");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTextArea(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JScrollPane createTextArea() {
textarea = new JTextArea(20, 60);
InputMap im = textarea.getInputMap();
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
im.put(ks, "del2EoL");
ActionMap am = textarea.getActionMap();
am.put("del2EoL", new Delete2EOL());
JScrollPane pane = new JScrollPane(textarea);
return pane;
}
#SuppressWarnings("serial")
private class Delete2EOL extends AbstractAction {
#Override
public void actionPerformed(ActionEvent e) {
int caretOffset = textarea.getCaretPosition();
int lineNumber = 0;
try {
lineNumber = textarea.getLineOfOffset(caretOffset);
int startOffset = textarea.getLineStartOffset(lineNumber);
int endOffset = textarea.getLineEndOffset(lineNumber);
textarea.replaceRange("", startOffset, endOffset);
} catch (BadLocationException ex) {
throw new RuntimeException(ex);
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new TestSamplePrograms().buildAndShowGui());
}
}
Related
I have a small text editor that I made in Java Swing with JTextArea.
I want to implement the following:
When the user presses Command+Backspace I want to remove all the text from the beginning of the line up to the cursor. How to implement this? I tried using KeyListeners but it doesn't work.
For example (before user presses Command+Backspace) ...
Result (after user presses Command+Backspace) ...
My code (Not 100% exact compared to the image):
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Main{
static JFrame frame = new JFrame();
static JTextArea textArea = new JTextArea();
static JScrollPane scrollPane = new JScrollPane(textArea);
public static void main(String[] args) throws BadLocationException {
frame.setTitle("Untitled");
addComponentsToFrame();
textArea.addKeyListener(new KeyListener(){
#Override
public void keyTyped(KeyEvent e) {
if(e.getKeyCode() == (Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() | KeyEvent.VK_BACK_SPACE)){
System.out.println("Delete"); //Placeholder
}
}
#Override
public void keyPressed(KeyEvent e) {}
#Override
public void keyReleased(KeyEvent e) {}
});
}
public static void addComponentsToFrame(){
scrollPane.setAutoscrolls(true);
frame.add(scrollPane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
For now when I have placed a print Statement as a place holder, since I don't know how to delete all the words from the beginning of the line up to the cursor (i.e. the logic).
Credits: #Abra
Solution:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.text.BadLocationException;
import java.awt.Toolkit;
public class TestSamplePrograms {
private JTextArea textarea;
private void buildAndShowGui() {
JFrame frame = new JFrame("Untitled");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTextArea(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JScrollPane createTextArea() {
textarea = new JTextArea(20, 60);
InputMap im = textarea.getInputMap();
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
im.put(ks, "del2EoL");
ActionMap am = textarea.getActionMap();
am.put("del2EoL", new Delete2EOL());
JScrollPane pane = new JScrollPane(textarea);
return pane;
}
#SuppressWarnings("serial")
private class Delete2EOL extends AbstractAction {
#Override
public void actionPerformed(ActionEvent e) {
int caretOffset = textarea.getCaretPosition();
int lineNumber = 0;
try {
lineNumber = textarea.getLineOfOffset(caretOffset);
int startOffset = textarea.getLineStartOffset(lineNumber);
int endOffset = textarea.getLineEndOffset(lineNumber);
textarea.replaceRange("", startOffset, endOffset);
} catch (BadLocationException ex) {
throw new RuntimeException(ex);
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new TestSamplePrograms().buildAndShowGui());
}
}
I am testing my keyListener in java.
My system in Ubuntu 14.04. I setup a panel in main and init the key listener. I also set focusable to true and do requestFocusInWindow.
But when I run the program, the println never shows up in console. confused of that.
package key;
import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Key extends JPanel{
public void action(){
KeyListener k = new KeyListener(){
#Override
public void keyPressed(KeyEvent k){
System.out.println("key is pressed!");
}
#Override
public void keyReleased(KeyEvent e){
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e){
System.out.println("key is typed!");
}
};
this.addKeyListener(k);
this.setFocusable(true);
this.requestFocusInWindow();
}
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setSize(400,300);
JPanel panel = new JPanel();
panel.setBackground(Color.BLUE);
frame.add(panel);
frame.setVisible(true);
Key k = new Key();
k.action();
}
}
any advice on that?
Use the key bindings API of KeyListener
Add k to frame before it's made visible
For example...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
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.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Key extends JPanel {
public void action() {
JLabel label = new JLabel("Waiting");
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = getActionMap();
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, false), "press.a");
actionMap.put("press.a", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
label.setText("Pressed A");
}
});
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, true), "release.a");
actionMap.put("release.a", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
label.setText("Waiting");
}
});
add(label);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBackground(Color.BLUE);
frame.add(panel);
Key k = new Key();
k.action();
frame.add(k, BorderLayout.SOUTH);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
How do I define a keyboard shortcut for top level special keys like german umlaut key Ä? I found a way to map unicode letters that are used for default american layout keys, see here. But the key event for the german umlaut key Ä is:
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=0,keyText=Unknown keyCode: 0x0,keyChar='ä',keyLocation=KEY_LOCATION_STANDARD,rawCode=222,primaryLevelUnicode=228,scancode=40] on frame0
The idea is to register a keyboard action:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class KeyStrokeForGermanUmlaut {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setPreferredSize(new Dimension(600, 400));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
final JLabel label = new JLabel("Text shall change with shortcut");
panel.add(label);
panel.registerKeyboardAction(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent event) {
label.setText("It is working!!!");
}
}, KeyStroke.getKeyStroke("control typed Ä"), JComponent.WHEN_IN_FOCUSED_WINDOW);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
});
}
}
you can to conjuring with JLabel, nothing happends for KeyEvents
should be start point with moving the focus to JFrames ContentPane (can be used as JPanel, but has BorderLayout in compare with plain JPanel - FlowLayout)
-
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class KeyStrokeForGermanUmlaut {
private JFrame frame = new JFrame();
private JLabel label = new JLabel("Text shall change with shortcut");
public KeyStrokeForGermanUmlaut() {
frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_MASK), "CTRL + A");
frame.getRootPane().getActionMap().put("CTRL + A", updateCol());
frame.setPreferredSize(new Dimension(600, 100));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(label);
frame.pack();
frame.setLocation(150, 150);
frame.setVisible(true);
}
private Action updateCol() {
return new AbstractAction("Hello World") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
label.setText(label.getText() + " presses");
}
};
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new KeyStrokeForGermanUmlaut();
}
});
}
}
.
.
EDIT see description in API getKeyStroke/ v.s. getKeyStrokeForEvent
then result is could be (little bit lost when and how to use modifiers SHIFT with uppercase form (ä and ú) for those two chars, maybe someone will help us with those pieces of KeyEvents)
from
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class KeyStrokeForGermanUmlaut {
private JFrame frame = new JFrame();
private JLabel label = new JLabel("Text shall change with shortcut");
public KeyStrokeForGermanUmlaut() {
frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke("typed ä"), "typed ä");
frame.getRootPane().getActionMap().put("typed ä", updateCol());
frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke("typed ú"), "typed ú");
frame.getRootPane().getActionMap().put("typed ú", updateCol1());
frame.setPreferredSize(new Dimension(600, 100));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(label);
frame.pack();
frame.setLocation(150, 150);
frame.setVisible(true);
}
private Action updateCol() {
return new AbstractAction("Hello World") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
label.setText(label.getText() + " presses - ä");
}
};
}
private Action updateCol1() {
return new AbstractAction("Hello World") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
label.setText(label.getText() + " presses - ú");
}
};
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new KeyStrokeForGermanUmlaut();
}
});
}
}
I am afraid there is something fishy in the handling of modifiers for CTRL.
That is: when inspecting the received key modifier=InputEvent.CTRL_MASK, extended modifier=InputEvent.CTRL_DOWN_MASK. And the API's javadoc is a bit suspicious.
Apart from that, Ä is not a special case, when "control" is left out.
To make it work, I had to add a dirty hack: register a key listener, that calls the action itself. I must be overseeing something.
For the rest I used an InputMap/ActionMap as intended. The input map does not seem to work, but to my understanding it does not work if added to a JTextField, or in the other answer (for Ä). The following works - in a horrible way.
final JLabel label = new JLabel("Text shall change with shortcut");
final KeyStroke key = KeyStroke.getKeyStroke((Character)'k',
InputEvent.CTRL_DOWN_MASK, false);
final Object actionKey = "auml";
final Action action = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent event) {
System.out.println("aha");
label.setText("It is working!!!");
}
};
label.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(java.awt.event.KeyEvent e) {
if (e.isControlDown() && e.getKeyChar() == 'ä') {
System.out.println("Ctrl-ä");
label.getActionMap().get(actionKey).actionPerformed(null);
// return;
}
super.keyPressed(e);
}
});
label.getInputMap().put(key, actionKey);
label.getActionMap().put(actionKey, action);
Ä, \xC4, Ä, Ä, %C4, %C3%84
There are the code for Ä. Please try with this, maybe one them will work for you.
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();
}
});
}
}
I have a problem with my JLayeredPane, I am probably doing something incredibly simple but I cannot wrap my head around it. The problem i have is that all the components are merged together and have not order. Could you please rectify this as I have no idea. The order I am trying to do is have a layout like this
output
label1 (behind)
input (in Front)
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class window extends JFrame implements KeyListener {
/**
*
*/
private static final long serialVersionUID = 7092006413113558324L;
private static int NewSize;
public static String MainInput;
public static JLabel label1 = new JLabel();
public static JTextField input = new JTextField(10);
public static JTextArea output = new JTextArea(main.Winx, NewSize);
public window() {
super("Satine. /InDev-01/");
JLabel label1;
NewSize = main.Winy - 20;
setLayout(new BorderLayout());
output.setToolTipText("");
add(input, BorderLayout.PAGE_END);
add(output, BorderLayout.CENTER);
input.addKeyListener(this);
input.requestFocus();
ImageIcon icon = new ImageIcon("C:\\Users\\" + System.getProperty("user.name") + "\\AppData\\Roaming\\.Satine\\img\\textbox.png", "This is the desc");
label1 = new JLabel(icon);
add(label1, BorderLayout.PAGE_END);
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_ENTER) {
try {
MainMenu.start();
} catch (IOException e1) {
System.out.print(e1.getCause());
}
}
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
}
}
And the main class.
import java.awt.Container;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
public class main {
public static int Winx, Winy;
private static JLayeredPane lpane = new JLayeredPane();
public static void main(String[] args) throws IOException{
Winx = window.WIDTH;
Winy = window.HEIGHT;
window Mth= new window();
Mth.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Mth.setSize(1280,720);
Mth.setVisible(true);
lpane.add(window.label1);
lpane.add(window.input);
lpane.add(window.output);
lpane.setLayer(window.label1, 2, -1);
lpane.setLayer(window.input, 1, 0);
lpane.setLayer(window.output, 3, 0);
Mth.pack();
}
}
Thank you for your time and I don't expect the code to be written for me, all I want is tips on where I am going wrong.
I recommend that you not use JLayeredPane as the overall layout of your GUI. Use BoxLayout or BorderLayout, and then use the JLayeredPane only where you need layering. Also, when adding components to the JLayeredPane, use the add method that takes a Component and an Integer. Don't call add(...) and then setLayer(...).
Edit: it's ok to use setLayer(...) as you're doing. I've never used this before, but per the API, it's one way to set the layer.
e.g.,
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class LayeredPaneFun extends JPanel {
public static final String IMAGE_PATH = "http://duke.kenai.com/" +
"misc/Bullfight.jpg";
public LayeredPaneFun() {
try {
BufferedImage img = ImageIO.read(new URL(IMAGE_PATH));
ImageIcon icon = new ImageIcon(img);
JLabel backgrndLabel = new JLabel(icon);
backgrndLabel.setSize(backgrndLabel.getPreferredSize());
JPanel forgroundPanel = new JPanel(new GridBagLayout());
forgroundPanel.setOpaque(false);
JLabel fooLabel = new JLabel("Foo");
fooLabel.setFont(fooLabel.getFont().deriveFont(Font.BOLD, 32));
fooLabel.setForeground(Color.cyan);
forgroundPanel.add(fooLabel);
forgroundPanel.add(Box.createRigidArea(new Dimension(50, 50)));
forgroundPanel.add(new JButton("bar"));
forgroundPanel.add(Box.createRigidArea(new Dimension(50, 50)));
forgroundPanel.add(new JTextField(10));
forgroundPanel.setSize(backgrndLabel.getPreferredSize());
JLayeredPane layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(backgrndLabel.getPreferredSize());
layeredPane.add(backgrndLabel, JLayeredPane.DEFAULT_LAYER);
layeredPane.add(forgroundPanel, JLayeredPane.PALETTE_LAYER);
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(new JScrollPane(new JTextArea("Output", 10, 40)));
add(layeredPane);
} catch (MalformedURLException e) {
e.printStackTrace();
System.exit(1);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("LayeredPaneFun");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new LayeredPaneFun());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}