Im currently working on simply text editor. But im stuck.
I divided my program into three differend classes:
Notepad - main class responsible for creating gui.
ButtonPanel - creating button, action listeners, jcomboboxes etc.
WriteArea - creating area where we can write.
And to the point, in ButtonPanel class im creating JComboBox, where you can choose font type and listening to the event, and when the event occurs, assing 'currentFont' value from JComboBox. But I cant send updated 'currenFont' to the WriteArea, and my question is how to refresh this class to get currentFont variable.
BTW.
IF you see another mistakes or just bad coding stuff, dont be shy and write that :D
package SimpleNotepad;
import javax.swing.*;
import java.awt.*;
public class Notepad extends JFrame {
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Notepad();
}
});
}
public Notepad(){
ButtonPanel buttonPanel = new ButtonPanel();
WriteArea writeArea = new WriteArea(buttonPanel);
//setSize(800, 600);
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(buttonPanel, BorderLayout.NORTH);
add(writeArea);
setJMenuBar(buttonPanel.menuBar);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
}
and ButtonPanel.java
package SimpleNotepad;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ButtonPanel extends JPanel {
JMenuBar menuBar;
private String currentFont = "Arial";
private String currentStyle;
private int currentSize;
private String[] fontTypes = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
private String[] fontStyles = {"Plain", "Bold", "Italic"};
private Integer[] fontSizes = {9, 10, 11, 12, 13, 14};
public ButtonPanel(){
menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
menuBar.add(menu);
JMenuItem menuOpen = new JMenuItem("Open");
JMenuItem menuZapisz = new JMenuItem("Save");
menu.add(menuOpen);
menu.add(menuZapisz);
Box theBox = Box.createHorizontalBox();
JComboBox fontList = new JComboBox(fontTypes);
JComboBox fontStyle = new JComboBox(fontStyles);
JComboBox fontSize = new JComboBox(fontSizes);
fontList.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JComboBox comboBox = (JComboBox) e.getSource();
currentFont = (String)comboBox.getSelectedItem();
System.out.println(currentFont);
}
});
JButton fontColor = new JButton("Font Color");
JButton backgroundColor = new JButton("Background Color");
theBox.add(fontList);
theBox.add(fontStyle);
theBox.add(fontSize);
theBox.add(fontColor);
theBox.add(backgroundColor);
add(theBox);
}
public String getCurrentFont() {
System.out.println(currentFont);
return currentFont;
}
}
WriteArea.java
package SimpleNotepad;
import javax.swing.*;
import java.awt.*;
public class WriteArea extends JPanel {
JTextArea textArea = new JTextArea(20, 50);
private ButtonPanel buttonPanel;
public WriteArea(ButtonPanel buttonPanel){
this.buttonPanel = buttonPanel;
String fontName = buttonPanel.getCurrentFont();
Font font = new Font(fontName, Font.ITALIC, 12);
textArea.setForeground(Color.WHITE);
textArea.setBackground(Color.BLACK);
textArea.setFont(font);
JScrollPane scrollPane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
add(scrollPane);
}
}
I don't know if this solution is very elegant, but it works for me: Let the WriteArea class extend KeyListener and add the textArea to this KeyListener. You can then set the font in the keyPressed method. This will check the selcted font every time a key is pressed and the WriteArea is focused (it needs to be focused if you want to type something into it). Here the parts that have changed:
public class WriteArea extends JPanel implements KeyListener{
//...
textArea.addKeyListener(this);
//...
}
#Override
public void keyPressed(KeyEvent arg0) {
if (this.getFont().getFontName() != buttonPanel.getCurrentFont()) {
textArea.setFont(new Font(buttonPanel.getCurrentFont(), Font.ITALIC, 12));
}
}
Note: Curently only works for the font family, but you should be able to extend this to work with size and style aswell. Also your code appears to be very clean to me, I didn't know that you could cast an ActionEvent the way you did.
Related
I have a JButton that I would like to keep at the very right of a JTextField, regardless of how I scale the window. I am aware of BorderLayout.EAST, but that doesn't seem to work. This is my current code (userText is my JTextField):
imageButton = new JButton("Attach an Image");
if(System.getProperty("os.name").equals("Mac OS X")){
imageButton.setLocation(455, 0);
imageButton.setSize(150, 30);
} else {
imageButton.setLocation(435, 0);
imageButton.setSize(150, 20);
}
imageButton.addActionListener(
//SOME FUNCTIONALITY CODE HERE
);
userText.add(imageButton);
I know this code is very bad. It produces this if I don't resale anything (disregard what the message is):
So this looks all fine (sorry I cropped it a bit poorly), but when I resale it...
This is obviously not good looking at all. When I chamge userText.add(imageButton) to userText.add(imageButton, BorderLayout.EAST) the button simply stays in the top left corner. When I tried adding this to the JFrame, it was just a large button to the right side of the JTextArea, so I'm not quite sure what to do?
So, how can I get the button stay at the right side of the JTextField and should I even be adding the button to the JTextField or should I be adding it to some other component?
As per request here is a simple but full example (sorry about the indentation):
public class Test extends JFrame{
private JTextField userText;
private JButton imageButton;
private JTextArea chatWindow;
public Test(){
super("Test");
userText = new JTextField();
add(userText, BorderLayout.NORTH);
imageButton = new JButton("Problem Button");
if(System.getProperty("os.name").equals("Mac OS X")){
imageButton.setLocation(455, 0);
imageButton.setSize(150, 30);
}
else{
imageButton.setLocation(435, 0);
imageButton.setSize(150, 20);
}
userText.add(imageButton);
chatWindow = new JTextArea();
setSize(600, 300);
setVisible(true);
}
public static void main(String[] args) {
Test test = new Test();
}
}
Just use a JPanel for the button. Set this panel layout to FlowLayout and set its alignment to RIGHT. Then add it to the NORTH position of your frame.
Here is a sample code:
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class FrameTest extends JFrame {
private JTextField userText;
private JButton imageButton;
private JTextArea chatWindow;
public FrameTest() {
super("Test");
userText = new JTextField();
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.add(userText, BorderLayout.CENTER);
imageButton = new JButton("Problem Button");
if (System.getProperty("os.name").equals("Mac OS X")) {
imageButton.setLocation(455, 0);
imageButton.setSize(150, 30);
}
else {
imageButton.setLocation(435, 0);
imageButton.setSize(150, 20);
}
topPanel.add(imageButton, BorderLayout.EAST);
add(topPanel, BorderLayout.NORTH);
chatWindow = new JTextArea();
setSize(600, 300);
setVisible(true);
}
public static void main(String[] args) {
FrameTest test = new FrameTest();
}
}
Well I am a newbie in Java and i have written this simple case converter program:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class caseconversion extends JFrame{
private JTextField tf;
private JCheckBox boldbox;
private JCheckBox italicbox;
private JButton up;
private JButton low;
public caseconversion(){
super ("Case Converter");
setLayout(new FlowLayout());
tf=new JTextField("Hello whats up Buddy !!",25);
tf.setFont(new Font("Segoe Print",Font.PLAIN,15));
add(tf);
boldbox = new JCheckBox("Bold");
italicbox = new JCheckBox("Italic");
add(boldbox);
add(italicbox);
up=new JButton("Upper Case");
low=new JButton("Lowercase");
add(up);
add(low);
HandlerClass handler = new HandlerClass();
boldbox.addItemListener(handler);
italicbox.addItemListener(handler);
up.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
tf.setText(tf.getText().toUpperCase());
}
}
);
low.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
tf.setText(tf.getText().toLowerCase());
}
}
);
}
private class HandlerClass implements ItemListener {
//For Checkboxes
public void itemStateChanged(ItemEvent event){
Font font= null;
if(boldbox.isSelected()&&italicbox.isSelected())
font = new Font("Segoe Print",Font.BOLD + Font.ITALIC ,15);
else if(boldbox.isSelected())
font = new Font("Segoe Print",Font.BOLD ,15);
else if(italicbox.isSelected())
font = new Font("Segoe Print",Font.ITALIC ,15);
else
font= new Font("Segoe Print",Font.PLAIN,15);
tf.setFont(font);
}
}
public static void main(String arg[]){
caseconversion go = new caseconversion();
go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
go.setSize(400,250);
go.setVisible(true);
}
}
Its working fine but i want to display JTextField tf in center,boldbox&italicbok on next line in center and Similarly JButtons on 3rd line in Center Can you please tell me how to do it.
The most simple solution (with minimal changes to the original code) is probably to put each row into one JPanel (where each JPanel has a FlowLayout), and arrange these 3 panels using a GridLayout
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class caseconversion extends JFrame{
private JTextField tf;
private JCheckBox boldbox;
private JCheckBox italicbox;
private JButton up;
private JButton low;
public caseconversion(){
super ("Case Converter");
setLayout(new GridLayout(0,1));
JPanel p = null;
p = new JPanel();
tf=new JTextField("Hello whats up Buddy !!",25);
tf.setFont(new Font("Segoe Print",Font.PLAIN,15));
p.add(tf);
add(p);
p = new JPanel();
boldbox = new JCheckBox("Bold");
italicbox = new JCheckBox("Italic");
p.add(boldbox);
p.add(italicbox);
add(p);
p = new JPanel();
up=new JButton("Upper Case");
low=new JButton("Lowercase");
p.add(up);
p.add(low);
add(p);
HandlerClass handler = new HandlerClass();
boldbox.addItemListener(handler);
italicbox.addItemListener(handler);
up.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
tf.setText(tf.getText().toUpperCase());
}
}
);
low.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
tf.setText(tf.getText().toLowerCase());
}
}
);
}
private class HandlerClass implements ItemListener {
//For Checkboxes
public void itemStateChanged(ItemEvent event){
Font font= null;
if(boldbox.isSelected()&&italicbox.isSelected())
font = new Font("Segoe Print",Font.BOLD + Font.ITALIC ,15);
else if(boldbox.isSelected())
font = new Font("Segoe Print",Font.BOLD ,15);
else if(italicbox.isSelected())
font = new Font("Segoe Print",Font.ITALIC ,15);
else
font= new Font("Segoe Print",Font.PLAIN,15);
tf.setFont(font);
}
}
public static void main(String arg[]){
caseconversion go = new caseconversion();
go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
go.setSize(400,250);
go.setVisible(true);
}
}
Note that you also have to think about the resizing behavior. Should these 3 rows always span the full height of the frame, or should they be compactly pushed to the top border of the frame?
However, a general hint (that seems to be underrated by newbies) is nesting: There's nothing wrong with creating a new JPanel in order to achieve a particular layout. Usually, a more "clean" solution to achieve this is to group several GUI components logically (and not re-using such a helper variable like the JPanel p that I used in the example).
If you using eclipse, i know a way that helped me.
JWindowbuilder: http://www.eclipse.org/windowbuilder/
If not you should look at this too:
http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
greetings Visores
i changed it the way you want with the WindowBuilder, i hope you like it :D
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class caseconversion extends JFrame {
private JTextField tf;
private JCheckBox boldbox;
private JCheckBox italicbox;
private JButton up;
private JButton low;
private Box verticalBox;
private Box horizontalBox;
private Box horizontalBox_1;
private Box horizontalBox_2;
private Component horizontalStrut;
private Component horizontalStrut_1;
private Component verticalStrut;
public caseconversion() {
super("Case Converter");
HandlerClass handler = new HandlerClass();
getContentPane().setLayout(
new BoxLayout(getContentPane(), BoxLayout.X_AXIS));
verticalBox = Box.createVerticalBox();
getContentPane().add(verticalBox);
horizontalBox = Box.createHorizontalBox();
verticalBox.add(horizontalBox);
horizontalStrut_1 = Box.createHorizontalStrut(20);
horizontalBox.add(horizontalStrut_1);
tf = new JTextField("Hello whats up Buddy !!", 25);
tf.setMaximumSize(new Dimension(2147483647, 60));
horizontalBox.add(tf);
tf.setFont(new Font("Segoe Print", Font.PLAIN, 15));
horizontalStrut = Box.createHorizontalStrut(20);
horizontalBox.add(horizontalStrut);
horizontalBox_1 = Box.createHorizontalBox();
verticalBox.add(horizontalBox_1);
boldbox = new JCheckBox("Bold");
horizontalBox_1.add(boldbox);
italicbox = new JCheckBox("Italic");
horizontalBox_1.add(italicbox);
italicbox.addItemListener(handler);
boldbox.addItemListener(handler);
horizontalBox_2 = Box.createHorizontalBox();
verticalBox.add(horizontalBox_2);
up = new JButton("Upper Case");
horizontalBox_2.add(up);
low = new JButton("Lowercase");
horizontalBox_2.add(low);
verticalStrut = Box.createVerticalStrut(20);
verticalBox.add(verticalStrut);
low.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
tf.setText(tf.getText().toLowerCase());
}
});
up.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
tf.setText(tf.getText().toUpperCase());
}
});
}
private class HandlerClass implements ItemListener {
// For Checkboxes
public void itemStateChanged(ItemEvent event) {
Font font = null;
if (boldbox.isSelected() && italicbox.isSelected())
font = new Font("Segoe Print", Font.BOLD + Font.ITALIC, 15);
else if (boldbox.isSelected())
font = new Font("Segoe Print", Font.BOLD, 15);
else if (italicbox.isSelected())
font = new Font("Segoe Print", Font.ITALIC, 15);
else
font = new Font("Segoe Print", Font.PLAIN, 15);
tf.setFont(font);
}
}
public static void main(String arg[]) {
caseconversion go = new caseconversion();
go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
go.setSize(400, 250);
go.setVisible(true);
}
}
Well, you can add BorderLayout as follows, for the JTextField :
add(tf,BorderLayout.NORTH);
and add 2 JPanel items :-
private JPanel panel1;
private JPanel panel2;
and initialize them into constructor as follows:-
panel1 =new JPanel();
panel2 =new JPanel();
and add this code
panel1.add(boldbox);
panel1.add(italicbox);
add(panel1,BorderLayout.CENTER);
panel2.add(up);
panel2.add(low);
add(panel2,BorderLayout.SOUTH);
I hope this help you.
I am implementing changes to a minesweeper game. One of these things is the difficulty. I have managed to do this and its working, but as the game board (in its own Jpanel) gets bigger & smaller (depending on the difficulty), I cannot get the JFrame to resize automatically. I am using:
setPreferredSize(new Dimension(WIDTH, HEIGHT));
to set the initial size of the window, but this makes it REALLY tiny, as in only showing the word 'File' from the JMenuBar. I have to resize it manually.
I tried setSize() and things like frame.pack() on the ActionListener event, but I cannot seem to get it to resize.
Any tips on what code/methods to use.
edit: code posted
package mines;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SetupFrame extends JFrame {
private final int WIDTH = 600;
private final int HEIGHT = 500;
public JFrame frame;
public JMenuBar menubar;
public JMenu file;
public JMenu levels;
public JMenu help;
public JMenuItem login;
public JMenuItem save;
public JMenuItem resume;
public JMenuItem exit;
public JMenuItem easy;
public JMenuItem medium;
public JMenuItem hard;
private JLabel statusbar;
public JPanel main;
public JPanel buttonPanel;
public JPanel saved;
public JPanel game;
public Board mineGame;
public JButton ngButton;
public JButton undoButton;
public JButton redoButton;
public JTabbedPane tp;
public String[] levelPicker;
public JComboBox levelSelect;
public JFileChooser chooser;
public String filename;
public int difficulty;
public SetupFrame(){
frame = new JFrame();
String filename = JOptionPane.showInputDialog(frame, "Enter Your Name.");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setTitle("Minesweeper");
//menubar, menus, menu items
menubar = new JMenuBar();
setJMenuBar(menubar);
file = new JMenu("File");
help = new JMenu("Help");
menubar.add(file);
menubar.add(help);
login = new JMenuItem("Login..");
save = new JMenuItem("Save..");
resume = new JMenuItem("Resume..");
exit = new JMenuItem("Exit");
file.add(login);
file.add(save);
file.add(resume);
file.addSeparator();
file.add(exit);
statusbar = new JLabel("");
chooser = new JFileChooser(); // new File Chooser for saved tab
undoButton = new JButton(" Undo "); //undo Button for game panel
ngButton = new JButton(" New Game ");//new game Button for game panel
redoButton = new JButton(" Redo");//redo Button for game panel
main = new JPanel(new BorderLayout()); //new panel for main game
//main.add(mineGame, BorderLayout.CENTER); //add instance mineGame to main panel
game = new JPanel(new BorderLayout());// new panel for game tab
main.add(game, BorderLayout.CENTER); //add the mineGames panel to game panel
game.add(statusbar, BorderLayout.SOUTH); //add statusbar to bottom of game panel
//game.add(button, BorderLayout.NORTH); // add buttons (eventually be redo, undo, new game)
saved = new JPanel(); // create new panel for the saved tab
saved.add(chooser);//add the File Chooser to the saved tab
String[] levelPicker = {"Easy", "Medium", "Hard"};
levelSelect = new JComboBox(levelPicker);
levelSelect.setSelectedIndex(0);
//levelSelect.addActionListener(this);
buttonPanel = new JPanel();
buttonPanel.add(undoButton);
buttonPanel.add(ngButton);
buttonPanel.add(redoButton);
buttonPanel.add(levelSelect);
main.add(buttonPanel, BorderLayout.NORTH);
//create & add the tabs
tp = new JTabbedPane();
tp.addTab ("Game", main);
tp.addTab ("Saved", saved);
tp.addTab ("Statistics", null);
add(tp);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setResizable(true);
setVisible(true);
frame.pack();
class listener implements ActionListener{
public void actionPerformed (ActionEvent e)
{
if(e.getSource() == ngButton){
//JOptionPane.showInputDialog(frame, "Do You want To Save");
newMineGame();
}
JComboBox cb = (JComboBox)e.getSource();
String picker = (String)cb.getSelectedItem();
if (picker == "Easy"){
difficulty = 0;
newMineGame();
}
if (picker == "Medium"){
difficulty = 1;
newMineGame();
frame.pack();
}
if (picker == "Hard"){
difficulty = 2;
newMineGame();
frame.pack();
}
}
private void newMineGame() {
game.removeAll();
mineGame = new Board(statusbar, difficulty);
game.add(mineGame, BorderLayout.CENTER);
game.add(statusbar, BorderLayout.SOUTH);
repaint();
}
}
ngButton.addActionListener(new listener());
undoButton.addActionListener(new listener());
redoButton.addActionListener(new listener());
levelSelect.addActionListener(new listener());
}
public static void main(String[] args) {
new SetupFrame();
}
One of these things is the difficulty. I have managed to do this and
its working, but as the game board (in its own Jpanel) gets bigger &
smaller (depending on the difficulty), I cannot get the JFrame to
resize automatically.
and
tried setSize() and things like frame.pack() on the ActionListener
event, but I cannot seem to get it to resize.
JFrame.pack() works in case
that all JComponents representing mines (there is best of ways to use JToggleButton) returns properly PreferredSize back to its parent (JPanel)
parent (JPanel) laid by GridLayout (very simple)
and there are two ways how, when, where to JFrame.pack()
use CardLayout, the next code line after swithching Card is JFrame.pack()
remove old JPanel (from JFrame) and replace with new, then you need to call JFrame.(re)validate(), JFrame.repaint() and JFrame.pack() as last code lines
maybe there is another issue, important is code ordering in the case that is there settings for JFrame.setResizable(false);
after your edit
use Cardlayout
there you miss code lines (don't to extends JFrame, create this Object as Local variable) JFrame.(re)validate(), JFrame.repaint() and JFrame.pack() as last code lines in private void newMineGame() {
but I dont understand what you mean by: "there you miss code lines
(don't to extends JFrame, create this Object as Local variable) ;
code could be
import javax.swing.*;
public class SetupFrame {
private JFrame frame;
private JMenuBar menubar = new JMenuBar();
private Board mineGame;
public SetupFrame() {
//there add required JComponents
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setTitle("Minesweeper");
frame.setJMenuBar(menubar);
frame.add(mineGame);
//frame.setPreferredSize(new Dimension(WIDTH, HEIGHT));
//frame.setResizable(true);//not neccessary
frame.pack();
frame.setVisible(true);
}
private void newMineGame() {
//remove old Board
//add a new Board
frame.validate();
frame.repaint();
frame.pack();
}
private static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new SetupFrame();
}
});
}
}
Here is your mistake:
frame.pack();
Why do you need frame if your SetupFrame actually extends from JFrame? Change this line by just pack() and it will work.
#mKorbel already posted a complete and very useful explanation about pack() behavior (thank you).
Update
Also in your listener class you'll get this exception when a JButton is pressed:
java.lang.ClassCastException: javax.swing.JButton cannot be cast to javax.swing.JComboBox
You need make this little change to avoid this:
class listener implements ActionListener{
public void actionPerformed (ActionEvent e) {
if(e.getSource() == ngButton){
//JOptionPane.showInputDialog(frame, "Do You want To Save");
newMineGame();
} else if(e.getSource() instanceof JComboBox){ // add this else-if block
JComboBox cb = (JComboBox)e.getSource();
String picker = (String)cb.getSelectedItem();
if (picker.equals("Easy")){ // <-- picker == "Easy" is not the proper way to compare string, use equals() method instead
difficulty = 0;
newMineGame();
}
if (picker.equals("Medium")){
difficulty = 1;
newMineGame();
//frame.pack(); <--- again, just use pack();
pack();
}
if (picker.equals("Hard")){
difficulty = 2;
newMineGame();
//frame.pack(); <--- again, just use pack();
pack();
}
}
}
Or even better, implement an ItemListener to listen JComboBox selection changes instead using an ActionListener
I have the following class which is a simple gui, and I would like to make it an applet so it can be displayed in the browser. I know how to embed the code into an html page(got that done)... but how can make my class an applet? Also, I assuming I don't need a web server just to display the applet in my browser...
package tester1;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class PanelTest implements ActionListener {
JFrame frame;
JLabel inputLabel;
JLabel outputLabel;
JLabel outputHidden;
JTextField inputText;
JButton button;
JButton clear;
JButton about;
public PanelTest() {
frame = new JFrame("User Name");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(3, 2, 10, 10));
//creating first row
JPanel row1 = new JPanel();
inputLabel = new JLabel("Your Name");
inputText = new JTextField(15);
// FlowLayout flow1 = new FlowLayout(FlowLayout.CENTER, 10, 10);
// row1.setLayout(flow1);
row1.add(inputLabel);
row1.add(inputText);
frame.add(row1);
//creating second row
JPanel row2 = new JPanel();
button = new JButton("Display");
clear = new JButton("Clear");
about = new JButton("About");
button.addActionListener(this);
clear.addActionListener(this);
about.addActionListener(new displayAbout());
row2.add(button);
row2.add(clear);
row2.add(about);
frame.add(row2);
//creating third row
JPanel row3 = new JPanel();
outputLabel = new JLabel("Output:", JLabel.LEFT);
outputHidden = new JLabel("", JLabel.RIGHT);
// FlowLayout flow2 = new FlowLayout(FlowLayout.CENTER, 10, 10);
// row3.setLayout(flow2);
row3.add(outputLabel);
row3.add(outputHidden);
frame.add(row3);
frame.pack();
frame.setVisible(true);
}
//same method listen for two different events
#Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if(command.equals("Display")) {
outputHidden.setText(inputText.getText());
}
if(command.equals("Clear")) {
outputHidden.setText("");
inputText.setText("");
}
}
//another way to listen for events
class displayAbout implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "Username 1.1 \n by Jorge L. Vazquez");
}
}
public static void main(String[] args) {
PanelTest frameTest = new PanelTest();
}
}
Use a JApplet rather than a JFrame. Make sure you read the relevant Java Tutorial, which covers the applet lifecycle methods like init, start, stop, and destroy.
As a side note, you should not be building your UI outside of the event dispatch thread.
Use a JApplet instead of a JFrame like veer said, but you must also remove frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);, frame.pack();, and frame.setVisible(true);
Also, replace main(String[] args) with init().
I would like to create a textwidget/component wich looks like the firefox address bar. I mean a Textfield wich allows me to place little Buttons inside the field (e.g. cancel/reload/...)
I tried customizing a JLayeredPane, by creating a custom layout manager which maximizes the Textfield, and places the remainder from right to left. My problem is that this gave painting issues, I would not always see the items I added over the textfield. This might be Jython related, I try suppling java.lang.Integer(1) to the JLayeredPane.add. However the Layers are ordered exactly reverse to what the documentation says.
TO cricumvent this I derived my own JLayeredPane class and redefined paint to call paintComponents which in turn iterates over all components and calls their paint method, starting with the textbox, the rest thereafter.
However I don't always get the updates right away, meaning the buttons are hidden/only partly displayed and I can't Interact with the button.
What do I have to acutally see the update on screen (is it hidden in a buffer?))
How can I make it so that I can interact with the buttons?
How can I shorten the Texxtfield, so that the text starts scrolling to the front before I reach the end of the Textfield so that the text does not get hidden by the buttons? I still want the Textfields area to extend under the buttons
edit: the button is only displayed in the right place after i make the window smaller, after that it is also clickable
edit2:
I took the freedom to boil the answer down to this, which hides away a lot of that button code/unneccessary stuff
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.*;
public class playground {
private Icon errorIcon = UIManager.getIcon("OptionPane.errorIcon");
private Icon infoIcon = UIManager.getIcon("OptionPane.informationIcon");
private Icon warnIcon = UIManager.getIcon("OptionPane.warningIcon");
public playground() {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(makeButton(), BorderLayout.WEST);
JTextField text = new JTextField(20);
text.setBorder(null);
panel.add(text, BorderLayout.CENTER);
JPanel buttonsPanel = new JPanel();
buttonsPanel.setOpaque(false);
buttonsPanel.setLayout(new GridLayout(1, 2, 2, 2));
buttonsPanel.add(makeButton());
buttonsPanel.add(makeButton());
panel.add(buttonsPanel, BorderLayout.EAST);
panel.setBackground(text.getBackground());
JMenuBar menuBar = new JMenuBar();
menuBar.add(panel);
menuBar.add(Box.createHorizontalGlue());
JFrame frame = new JFrame("MenuGlueDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(menuBar);
frame.pack();
frame.setVisible(true);
}
public JToggleButton makeButton() {
final JToggleButton button = new JToggleButton();
button.setFocusable(false);
button.setMargin(new Insets(0, 0, 0, 0));
button.setContentAreaFilled(false);
button.setBorder(null);
button.setIcon((errorIcon));
button.setRolloverIcon((infoIcon));
button.setSelectedIcon(warnIcon);
button.setPressedIcon(warnIcon);
button.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (button.isSelected()) {
} else {
}
}
});
return button;
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
playground menuGlueDemo = new playground();
}
});
}
}
may be could it be simple by using JMenuBar, with Auto complete ComboBox / JFextField for example
import java.awt.ComponentOrientation;
import javax.swing.*;
public class MenuGlueDemo {
public MenuGlueDemo() {
JMenuBar menuBar = new JMenuBar();
menuBar.add(createMenu("Menu 1"));
menuBar.add(createMenu("Menu 2"));
menuBar.add(createMenu("Menu 3"));
menuBar.add(new JSeparator());
menuBar.add(new JButton(" Seach .... "));
menuBar.add(new JTextField(" Seach .... "));
menuBar.add(new JComboBox(new Object[]{"height", "length", "volume"}));
menuBar.add(Box.createHorizontalGlue());
menuBar.add(createMenu("About"));
JFrame frame = new JFrame("MenuGlueDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(menuBar);
frame.pack();
frame.setVisible(true);
}
public JMenu createMenu(String title) {
JMenu m = new JMenu(title);
m.add("Menu item #1 in " + title);
m.add("Menu item #2 in " + title);
m.add("Menu item #3 in " + title);
if (title.equals("About")) {
m.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
}
return m;
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MenuGlueDemo menuGlueDemo = new MenuGlueDemo();
}
});
}
}
EDIT
I can simply but a text input and some buttons in a container with a proper layout and achieve [Textfield...] [B1] [B2] but I want [Textfield [B1] [B2]]
with proper LayoutManager
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.*;
public class MenuGlueDemo {
private Icon errorIcon = UIManager.getIcon("OptionPane.errorIcon");
private Icon infoIcon = UIManager.getIcon("OptionPane.informationIcon");
private Icon warnIcon = UIManager.getIcon("OptionPane.warningIcon");
public MenuGlueDemo() {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
JButton button = new JButton();
button.setFocusable(false);
//button.setMargin(new Insets(0, 0, 0, 0));
button.setContentAreaFilled(false);
button.setIcon((errorIcon));
button.setPressedIcon(warnIcon);
panel.add(button, BorderLayout.WEST);
JTextField text = new JTextField(20);
text.setBorder(null);
panel.add(text, BorderLayout.CENTER);
JPanel buttonsPanel = new JPanel();
buttonsPanel.setOpaque(false);
buttonsPanel.setLayout(new GridLayout(1, 2, 2, 2));
final JToggleButton toggleButton = new JToggleButton();
toggleButton.setFocusable(false);
toggleButton.setMargin(new Insets(0, 0, 0, 0));
toggleButton.setContentAreaFilled(false);
toggleButton.setIcon((errorIcon));
toggleButton.setRolloverIcon((infoIcon));
toggleButton.setSelectedIcon(warnIcon);
toggleButton.setPressedIcon(warnIcon);
toggleButton.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (toggleButton.isSelected()) {
} else {
}
}
});
buttonsPanel.add(toggleButton);
final JToggleButton toggleButton1 = new JToggleButton();
toggleButton1.setFocusable(false);
toggleButton1.setMargin(new Insets(0, 0, 0, 0));
toggleButton1.setContentAreaFilled(false);
toggleButton1.setIcon((errorIcon));
toggleButton1.setRolloverIcon((infoIcon));
toggleButton1.setSelectedIcon(warnIcon);
toggleButton1.setPressedIcon(warnIcon);
toggleButton1.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (toggleButton1.isSelected()) {
} else {
}
}
});
buttonsPanel.add(toggleButton1);
panel.add(buttonsPanel, BorderLayout.EAST);
panel.setBackground(text.getBackground());
JMenuBar menuBar = new JMenuBar();
menuBar.add(createMenu("Menu 1"));
menuBar.add(createMenu("Menu 2"));
menuBar.add(createMenu("Menu 3"));
menuBar.add(new JSeparator());
menuBar.add(new JButton(" Seach .... "));
menuBar.add(panel);
menuBar.add(new JComboBox(new Object[]{"height", "length", "volume"}));
menuBar.add(Box.createHorizontalGlue());
menuBar.add(createMenu("About"));
JFrame frame = new JFrame("MenuGlueDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(menuBar);
frame.pack();
frame.setVisible(true);
}
private JMenu createMenu(String title) {
JMenu m = new JMenu(title);
m.add("Menu item #1 in " + title);
m.add("Menu item #2 in " + title);
m.add("Menu item #3 in " + title);
if (title.equals("About")) {
m.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
}
return m;
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MenuGlueDemo menuGlueDemo = new MenuGlueDemo();
}
});
}
}
You may be able to adapt the approach shown in Component Border, which allows "a JTextField and a JButton to work together." The related article Text Prompt may also prove useful. Finally, consider JToolBar, illustrated here, as a flexible way to tie components together.