I'm in a bit of a situation here.I'm making a new program, when you click on the menu bar it opens a new window for the Licence, now here is the problem, how would I add text into that new window, here is my code for the new window:
JFrame frame = new JFrame("Licence");
frame.setSize(500,120);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
I know this is a easy question, I just can't think of the correct code for it.
You can try something like
JDialog dialog = new JDialog(your_frame_reference, "Licence");
dialog .setModal(true);
dialog .setLocationRelativeTo(null);
dialog. getContentPane().add(new JLabel(your_text);
dialog .setVisible(true);
You can use label
JFrame frame = new JFrame("Licence");
JLabel label = new JLabel("Text-Only Label");
label.setFont(new Font("Serif", Font.PLAIN, 36));
frame.add(label);
You can add text by creating JLabels like so:
JLabel label = new JLabel("Hello World");
This can then be added to your JFrame.
Try this Example
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestDialog {
protected static void initUI() {
JPanel pane = newPane("Label in frame");
JFrame frame = new JFrame("Title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(pane);
frame.pack();
frame.setVisible(true);
}
public static JPanel newPane(String labelText) {
JPanel pane = new JPanel(new BorderLayout());
pane.add(newLabel(labelText));
pane.add(newButton("Open dialog"), BorderLayout.SOUTH);
return pane;
}
private static JButton newButton(String label) {
final JButton button = new JButton(label);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Window parentWindow = SwingUtilities.windowForComponent(button);
JDialog dialog = new JDialog(parentWindow);
dialog.setLocationRelativeTo(button);
dialog.setModal(true);
dialog.add(newPane("Label in dialog"));
dialog.pack();
dialog.setVisible(true);
}
});
return button;
}
private static JLabel newLabel(String label) {
JLabel l = new JLabel(label);
l.setFont(l.getFont().deriveFont(24.0f));
return l;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
initUI();
}
});
}
}
Related
I'm trying to learn Java (not a programmer by profession).
I'm currently working on a calendar app with Postgres backend.
My app consists of a JFrame with two JPanels. One of those Panels is a CalendarView(MonthView, WeekView, or DayView), and the other a ButtonPanel.
The ButtonPanel has a button to add a new Event to the Calendar. This button opens a JDialog for entering Event details (startDate, endDate, title, etc).
The owner of the dialog is the JFrame. The dialog is modular.
The issues I have is that when the dialog is open, if I click on the parent window, the dialog disappears. If I then move the cursor outside the main application window and back in, the dialog reappears. I was under the impression that this should not happen with a modal component.
All feedback appreciated. I made a slimmed down SSCCE:
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import java.awt.*;
public class Calendar extends JFrame {
public Calendar() {
super("Calendar");
initGUI();
}
public void initGUI() {
JPanel calendarView = new JPanel();
calendarView.setPreferredSize(new Dimension(400, 400));
calendarView.setBorder(BorderFactory.createTitledBorder(new LineBorder(Color.BLACK), "Calendar view", TitledBorder.CENTER, TitledBorder.CENTER));
JPanel buttonPanel = new ButtonPanel();
buttonPanel.setBorder(BorderFactory.createTitledBorder(new LineBorder(Color.RED), "Button panel", TitledBorder.CENTER, TitledBorder.CENTER));
buttonPanel.setPreferredSize(new Dimension(200, 400));
this.getContentPane().add(calendarView, BorderLayout.CENTER);
this.getContentPane().add(buttonPanel, BorderLayout.WEST);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Calendar();
}
});
}
}
mport java.awt.*;
import java.awt.event.ActionListener;
import javax.swing.*;
public class ButtonPanel extends JPanel {
public ButtonPanel() {
initGui();
}
private void initGui() {
GridBagLayout gbag = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
this.setLayout(gbag);
JButton button = new JButton("Open dialog");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
new MyDialog((JFrame) ButtonPanel.this.getTopLevelAncestor());
}
});
gbag.setConstraints(button, gbc);
this.add(button);
}
}
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import java.awt.*;
public class MyDialog extends JDialog {
public MyDialog(JFrame owner) {
super(owner, "My dialog", true);
initGUI(owner);
}
private void initGUI(JFrame owner){
JOptionPane optionPane = new JOptionPane(createPanel(), JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION, null, createButtons(), createButtons()[0]);
this.add(optionPane, BorderLayout.CENTER);
this.pack();
this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
this.setLocationRelativeTo(owner);
this.setVisible(true);
}
private JPanel createPanel() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder(new LineBorder(Color.BLACK), "My dialog", TitledBorder.CENTER, TitledBorder.CENTER));
return panel;
}
private JButton[] createButtons() {
JButton[] buttons = new JButton[1];
JButton button = new JButton("Exit");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event){
MyDialog.this.dispose();
}
});
buttons[0] = button;
return buttons;
}
}
I had a CardLayout example working correctly with a button, then tried to convert it to work with keypress. I think the problem is that I don't have focus, but I can't set the focus to frame or panel successfully. Thanks!
I tried requestFocusInWindow from the frame and from the first panel shown, and that didn't help. I asked frame.getFocusOwner() and it returned null.
I thought that CardLayout would give the focus to the top element automatically, but while that worked when I had a button, it is not working now.
public class MyCardLayoutExample3 {
public static void main(String[] args){
MyCardLayoutExample3 game = new MyCardLayoutExample3();
game.display();
}
void display() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(300, 200);
CardLayout cardLayout = new CardLayout();
frame.getContentPane().setLayout(cardLayout);
MyGamePanel3 mgp3 = new MyGamePanel3("minigame A", Color.red);
frame.getContentPane().add(mgp3);
frame.getContentPane().add(new MyGamePanel3("minigame B", Color.green));
frame.getContentPane().add(new MyGamePanel3("minigame C", Color.blue));
frame.setVisible(true);
System.out.println("owner: " + frame.getFocusOwner()); //this prints null
}
}
class MyGamePanel3 extends JPanel implements KeyListener{
MyGamePanel3(String text, Color bg){
JLabel textLabel = new JLabel(text);
this.setBackground(bg);
this.add(textLabel);
}
#Override
public void keyTyped(KeyEvent e) {}
#Override
public void keyPressed(KeyEvent e) {
System.out.println("keyPressed worked");
}
#Override
public void keyReleased(KeyEvent e) {}
}
Changing to key bindings made the example work easily, thanks Abra. I never got the keyListener to work, despite trying the links above and many other links.
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
class MyGamePanel extends JPanel{
MyGamePanel(ActionListener alNext, String text, Color bg){
JButton buttonNext = new JButton("next");
buttonNext.addActionListener(alNext);
JLabel textLabel = new JLabel(text);
this.setBackground(bg);
this.add(textLabel);
this.add(buttonNext);
}
}
public class MyCardLayoutKeyBindingExample {
public static void main(String[] args){
MyCardLayoutKeyBindingExample game = new MyCardLayoutKeyBindingExample();
game.display();
}
void display() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(300, 200);
CardLayout cardLayout = new CardLayout();
//frame.getContentPane().setLayout(cardLayout);
JPanel mainPanel = new JPanel(cardLayout);
frame.add(mainPanel);
ActionListener al1 = e -> cardLayout.next(mainPanel);
mainPanel.add(new MyGamePanel(al1, "minigame A", Color.red));
mainPanel.add(new MyGamePanel(al1, "minigame B", Color.green));
mainPanel.add(new MyGamePanel(al1, "minigame C", Color.blue));
mainPanel.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "space");
Action kp = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
System.out.println("key pressed");
}
};
mainPanel.getActionMap().put("space", kp);
frame.setVisible(true);
}
}
I made a BoxLayout GUI and i'm wondering how i'd use an actionlistener to make the button close the window. If I try to put in RegisterNew.setVisible(false); in an actionlistener, it gives me an error
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class RegisterNew extends JFrame
{
public RegisterNew(int axis){
// creates the JFrame
super("BoxLayout Demo");
Container con = getContentPane();
con.setLayout(new BoxLayout(con, axis));
con.add(new JLabel("Enter your desired username"));
con.add(new JTextField());
con.add(new JLabel("Enter your password"));
con.add(new JTextField());
con.add(new JButton("Create Account"));
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String args[])
{
RegisterNew newDemo = new RegisterNew(BoxLayout.Y_AXIS);
}
}
I'm also trying to link this to ANOTHER GUI so that when you press a button, this one appears, but it gives me the same error as if i put
RegisterNew.setVisible(true); into the action listener
If that's a subordinate dialog window, then use a JDialog, not a JFrame.
If your ActionListener is an inner class then use RegisterNew.this.close();
Else you can get the window ancestor for the JButton using SwingUtilities.getWindowAncestor(button) and call close() or better dispose() on the Window returned.
Note that BoxLayout and layout managers in general have nothing to do with your current problem.
e.g.,
Test class that shows the new register dialog and that extracts information from it.
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class TestRegistration extends JPanel {
private JTextArea textArea = new JTextArea(30, 60);
public TestRegistration() {
JPanel bottomPanel = new JPanel();
bottomPanel.add(new JButton(new ShowRegisterNewAction()));
textArea.setFocusable(false);
textArea.setEditable(false);
setLayout(new BorderLayout());
add(new JScrollPane(textArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
add(bottomPanel, BorderLayout.PAGE_END);
}
private class ShowRegisterNewAction extends AbstractAction {
private RegisterNew registerNew = null;
public ShowRegisterNewAction() {
super("Show Register New Dialog");
putValue(MNEMONIC_KEY, KeyEvent.VK_S);
}
#Override
public void actionPerformed(ActionEvent e) {
if (registerNew == null) {
JButton btn = (JButton) e.getSource();
Window window = SwingUtilities.getWindowAncestor(btn);
registerNew = new RegisterNew(window, BoxLayout.PAGE_AXIS);
}
registerNew.setVisible(true);
String userName = registerNew.getUserName();
String password = new String(registerNew.getPassword());
textArea.append("User Name: " + userName + "\n");
textArea.append("Password: " + password + "\n");
textArea.append("\n");
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("TestRegistration");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TestRegistration());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
New Register class that holds the dialog and has code for displaying it and for extracting information from it. Uses BoxLayout.
import java.awt.Container;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class RegisterNew {
private JDialog dialog = null;
private JTextField nameField = new JTextField(10);
private JPasswordField passField = new JPasswordField(10);
public RegisterNew(Window window, int axis) {
dialog = new JDialog(window, "Register New", ModalityType.APPLICATION_MODAL);
Container con = dialog.getContentPane();
con.setLayout(new BoxLayout(con, axis));
con.add(new JLabel("Enter your desired username"));
con.add(nameField);
con.add(new JLabel("Enter your password"));
con.add(passField);
con.add(new JButton(new AcceptAction()));
dialog.pack();
dialog.setLocationRelativeTo(window);
}
public char[] getPassword() {
return passField.getPassword();
}
public String getUserName() {
return nameField.getText();
}
public void setVisible(boolean b) {
dialog.setVisible(b);
}
private class AcceptAction extends AbstractAction {
public AcceptAction() {
super("Accept");
putValue(MNEMONIC_KEY, KeyEvent.VK_A);
}
#Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
}
}
My question is similar to this one: JTable Cell Update doesn't work.
However, I am using JDialog instead of a JTable specified in above link. I have a custom class which extends JDialog. I use JEditorPane as a text-component in that dialog and create simple OK, Cancel buttons. Now the problem is, when I enter something in the JEdiorPane and presses OK button, the value is not applied to the text-component until I move the focus out of a JDialog or hit tab/ENTER.
I want the container to be notified that I am done with editing as soon as I press the OK button. In short I want to explicitly have a feature similar to stopCellEditing(). How can I do that?
See this example which seems to work correctly and does the same thing as you described:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class TestEditorPaneDialog {
public void init() {
final JFrame frame = new JFrame();
JButton clickMe = new JButton("Click me");
clickMe.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
showDialog(frame);
}
});
frame.add(clickMe);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
showDialog(frame);
}
private void showDialog(final JFrame frame) {
final JDialog dialog = new JDialog(frame, true);
final JEditorPane pane = new JEditorPane();
pane.setText("Type something here");
JPanel south = new JPanel();
JPanel buttons = new JPanel(new GridLayout(1, 0, 10, 10));
JButton ok = new JButton("OK");
ok.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
JOptionPane.showMessageDialog(frame, "You have typed in: " + pane.getText());
}
});
JButton cancel = new JButton("Cancel");
cancel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
buttons.add(ok);
buttons.add(cancel);
south.add(buttons);
dialog.add(new JScrollPane(pane));
dialog.add(south, BorderLayout.SOUTH);
dialog.setSize(250, 150);
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestEditorPaneDialog().init();
}
});
}
}
I am trying to extend the StyledEditorKit in Swing to be able to include a JLabel inside the editor. I was able to do that and this is what I got so far. In the image below, the highlighted text button is of type JLabel whereas the rest of the text is normal text.
As you can see the label renders a little below than the normal text. How do I align its top with top of the remaining text?
Here is the code for the view that is used to create this label element:
class ComponentView(Element elem) {
#Override
protected Component createComponent() {
JLabel lbl = new JLabel("");
lbl.setOpaque(true);
lbl.setBackground(Color.red);
try {
int start = getElement().getStartOffset();
int end = getElement().getEndOffset();
String text = getElement().getDocument().getText(start, end - start);
lbl.setText(text);
} catch (BadLocationException e) {}
return lbl;
}
}
Try adjusting Component.getAlignmentY that controls the positioning of component relative to the text baseline as suggested in ComponentView.
You could also try using JTextPane that provides easier support for embedded components. Components can be added using insertComponent() method. Here is an example, it also demos setAlignmentY:
import java.awt.BorderLayout;
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.JTextPane;
import javax.swing.SwingUtilities;
public class TextPaneDemo {
private static void createAndShowGUI() {
final JTextPane pane = new JTextPane();
pane.setText("Some text");
JButton buttonButton = new JButton("Insert label");
buttonButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
JLabel label = new JLabel("label");
label.setAlignmentY(0.85f);
pane.insertComponent(label);
}
});
JPanel panel = new JPanel(new BorderLayout());
panel.add(buttonButton, BorderLayout.SOUTH);
panel.add(pane, BorderLayout.CENTER);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setSize(400, 200);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}