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();
}
}
Related
For some reason, when I run this code, my JFrame comes up as blank. I have been trying online tutorials for maybe an hour now, and I'm wondering if I'm misunderstanding something.
Here is the code:
public class Application {
public static JFrame f;
public static JButton submit;
public static JTextField unscramblee;
public static String scrambledWord, possibleWords;
public static JLabel possibleWordsDisplay;
public static JPanel UI;
public static JScrollPane scrollPane;
Application() {
f = new JFrame("test");
f.setResizable(true);
f.setLayout(null);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
UI = new JPanel();
scrollPane = new JScrollPane(UI);
unscramblee = new JTextField("test");
unscramblee.setBounds(240, 200, 400, 50);
submit = new JButton("Submit");
submit.setBounds(240, 350, 400, 100);
possibleWordsDisplay = new JLabel("possibleWordsDisplay - this is a display for words that are possible");
possibleWordsDisplay.setBounds(240, 0, 200, 200);
scrollPane.add(unscramblee);
scrollPane.add(submit);
scrollPane.add(possibleWordsDisplay);
f.getContentPane().add(scrollPane);
f.pack();
f.setSize(1280,720);
}
}
I hope this is enough information to help. Thanks.
(If anyone is wondering why the setSize method comes after the pack method, it's because the JFrame keeps collapsing on itself when I run it. If you also know how to fix that please tell me! I'd be very thankful.)
Setting bound manually is not a viable practice.
Instead use the appropriate Layout Managers for the desired layout.
The following is mre1 (note the comments) :
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
public class Application {
Application() {
JFrame f = new JFrame("test");
//f.setSize(1280,720); f.pack should automatically set the size
f.setResizable(true);
//f.setLayout(null); do not use null layout
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel UI = new JPanel(); // uses flowlayout by default
//UI.setBounds(0, 0, 1280, 720); do not set bounds. that the job of the layout manager
JTextField unscramblee = new JTextField("test", 10);
//unscramblee.setBounds(240, 200, 400, 50);
JButton submit = new JButton("Submit");
//submit.setBounds(240, 350, 400, 100);
JLabel possibleWordsDisplay = new JLabel("possibleWordsDisplay - this is a display for words that are possible");
//possibleWordsDisplay.setBounds(240, 0, 200, 200);
UI.add(unscramblee);
UI.add(submit);
UI.add(possibleWordsDisplay);
JScrollPane scrollPane = new JScrollPane(UI);
f.getContentPane().add(scrollPane); //uses borderlayout by default
f.pack();
f.setVisible(true); //make frame visible after construction is completed
}
public static void main(String[] args) {
new Application();
}
}
1 Always consider an mre when posting question or answers
When creating a GUI, consider following the below design to start:
private JFrame frame;
private JPanel contentPane;
public static void main(String[] args) {
GUI gui = new GUI();
gui.start();
}
private void start() {
frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
makeContent();
frame.setSize(500, 130);
frame.setVisible(true);
}
private void makeContent() {
contentPane = (JPanel) frame.getContentPane();
makePanel();
}
private void makePanel() {
JPanel ui = new JPanel();
ui.setLayout(new BoxLayout(ui, BoxLayout.Y_AXIS));
JLabel possibleWordsDisplay = new JLabel("possibleWordsDisplay - this is a display for words that are possible");
ui.add(possibleWordsDisplay);
JTextField unscramblee = new JTextField();
JScrollPane scroll = new JScrollPane(unscramblee);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
ui.add(scroll);
JButton submit = new JButton("Submit");
ui.add(submit);
contentPane.add(ui, BorderLayout.CENTER);
}
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.
So hello there :), this is my fist post here.
Lets get right into it:
My problem:
I put a calculator as a background image, than added a JButton to it.
My Problem(s):
When I start the program the calculator is quickly shown, then it vanishes and the button is shown
When I resize the window, the calculator shows up and the button dissapears
How can I make this work?
Heres my code:
import javax.swing.*;
import javax.*;
import java.awt.*;
import java.awt.event.*;
public class Calculator extends JFrame {
private ImageIcon image;
private JLabel label;
Calculator() {
image = new ImageIcon(getClass().getResource("TStiny.png"));
label = new JLabel(image);
add(label);
}
public static void main (String args[]) {
Calculator gui = new Calculator();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setTitle("Texas Instruments TI-30XIIS");
gui.pack();
gui.setVisible(true);
JPanel panel = new JPanel();
gui.add(panel);
JButton button7 = new JButton();
button7.setIcon(new ImageIcon(Calculator.class.getResource("button_7.png")));
button7.setVisible(true);
button7.setBorderPainted(false);
button7.setBounds(90, 445, 45, 35);
panel.add(button7);
}
Thanks in advance! :)
You need to specify the layout and eventual position to which you want to add the component. JFrame uses BorderLayout by default.
If you want to use the default behavior, you should put a position on which to place the component:
public class Calculator extends JFrame {
private ImageIcon image;
private JLabel label;
Calculator() {
image = new ImageIcon(getClass().getResource("TStiny.png"));
label = new JLabel(image);
add(label, BorderLayout.LINE_START);
}
public static void main(String args[]) {
Calculator gui = new Calculator();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setTitle("Texas Instruments TI-30XIIS");
gui.pack();
gui.setVisible(true);
JPanel panel = new JPanel();
gui.add(panel, BorderLayout.LINE_END);
JButton button7 = new JButton();
button7.setIcon(new ImageIcon(Calculator.class.getResource("button_7.png")));
button7.setVisible(true);
button7.setBorderPainted(false);
button7.setBounds(90, 445, 45, 35);
panel.add(button7);
}
}
Another option is to specify a layout that does not want to specify a position - such as FlowLayout:
public class Calculator extends JFrame {
private ImageIcon image;
private JLabel label;
Calculator() {
setLayout(new FlowLayout());
image = new ImageIcon(getClass().getResource("TStiny.png"));
label = new JLabel(image);
add(label);
}
public static void main(String args[]) {
Calculator gui = new Calculator();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setTitle("Texas Instruments TI-30XIIS");
gui.pack();
gui.setVisible(true);
JPanel panel = new JPanel();
gui.add(panel);
JButton button7 = new JButton();
button7.setIcon(new ImageIcon(Calculator.class.getResource("button_7.png")));
button7.setVisible(true);
button7.setBorderPainted(false);
button7.setBounds(90, 445, 45, 35);
panel.add(button7);
}
}
My code is currently working fine, but whenever i compile, i get the Warning
C:\Users\etc\etc\FinalProject\AddItem.java uses unchecked or unsafe operations. Recompile with -Xlint:unchecked for details.
Should I do something about it, and if so, what? if my debugging is right, it appears to be caused by the content pane properties.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Canvas;
import javax.swing.JFrame;
import java.awt.Dimension;
import java.io.*;
class AddItem extends JFrame implements ActionListener
{
//text
private static JLabel TechforTeachingTitle;
private static JLabel TechforTeachingSubTitle;
//images
private static JLabel Logo;
//buttons
private JButton submitButton;
private static final int BUTTON_WIDTH = 100;
private static final int BUTTON_HEIGHT = 30;
//variables
public static void main(String[] args)
{
AddItem ProjectFrame = new AddItem();
ProjectFrame.setVisible(true); // Display the frame
//for combobox
//new AddItem().setVisible(true);
}
public AddItem ( )
{
//font properties
Font TitleFont = new Font("Serif", Font.BOLD, 80);
Font subFont = new Font("Serif", Font.BOLD, 40);
// set the frame properties
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("Inventory system");
setSize(900, 700);
setLocationRelativeTo(null);
setResizable(true);
// set the content pane properties
Container contentPane = getContentPane();
contentPane.setLayout(null);
contentPane.setBackground(Color.decode("#FDF3E7"));
//set text properties
TechforTeachingTitle = new JLabel();
TechforTeachingTitle.setText("Tech For Teaching");
TechforTeachingTitle.setBounds(200, 30, 900, 95);
TechforTeachingTitle.setForeground(Color.decode("#8f8f8f"));
TechforTeachingTitle.setFont(TitleFont);
contentPane.add(TechforTeachingTitle);
TechforTeachingSubTitle = new JLabel();
TechforTeachingSubTitle.setText("Add an item");
TechforTeachingSubTitle.setBounds(400, 90, 900, 95); //left, top, length, height
TechforTeachingSubTitle.setForeground(Color.decode("#799177")); //7E8F7C (slightly less green)
TechforTeachingSubTitle.setFont(subFont);
contentPane.add(TechforTeachingSubTitle);
//set image properties
Logo = new JLabel(new ImageIcon("SmallLogo.png"));
Logo.setBounds(10,20,179,178); // //left, top, width, height
contentPane.add(Logo);
Logo.setVisible(true);
Logo.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e) {
setVisible(false);
FinalProject FP = new FinalProject();
FP.setVisible(true);
}
});
//set button properties
//for combobox
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//setLayout(null); //ONLY PROBLEM WITH THIS IS GETTING THE SCREEN TO APPEAR AT CORRECT SIZE
String[] values = {"Computer", "Monitor", "Keyboard"};
final JComboBox b = new JComboBox(values);
b.setEditable(true);
add(b);
b.setBounds(300, 300, 100, 50); //this works
add(b);
submitButton = new JButton("Submit");
submitButton.setBounds(700,600, BUTTON_WIDTH, BUTTON_HEIGHT);
submitButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String item=b.getSelectedItem().toString();
}
});
contentPane.add(submitButton);
//pack(); //not quite sure what this is for, but it makes the window tiny, so i commented it out
setLocationRelativeTo(null); //positions window center on screen
}
public void actionPerformed(ActionEvent event) // Actions
{
JButton clickedButton = (JButton) event.getSource();
String buttonText = clickedButton.getText();
}
}
you get the warning here I think:
final JComboBox b = new JComboBox(values);
to avoid this you have the following possibilities:
add SupressWarning above the JComboBox
#SuppressWarnings("unchecked")
final JComboBox b = new JComboBox(values);
or add SupressWarning above your method
#SuppressWarnings("rawtypes")
public AddItem ( )
or my favourite add the generic:
final JComboBox<Object> b = new JComboBox<Object>(values);
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().