.drawLine is not drawing onto JTabbedPane (Java) - java

Someone told me a way to paint onto a Jframe and it worked fine in the example, but now I have tabs it doesn't paint onto them.
I need the paint/drawLine to work in my Tabbed example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.io.*;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
public class GUI extends JTabbedPane implements ActionListener
{
static JFrame aWindow = new JFrame("Project");
JTabbedPane myTabs = new JTabbedPane();
JPanel loginMainPanel = new JPanel();
JPanel displayMainPanel = new JPanel();
JPanel editMainPanel = new JPanel();
JTextField myText1 = new JTextField("");
JTextField myText2 = new JTextField("");
JTextField myText3 = new JTextField("");
JLabel loginLabel = new JLabel("Username:");
JTextField loginField = new JTextField();
JLabel loginLabel2 = new JLabel("Password:");
JPasswordField loginPass = new JPasswordField();
JButton displayButton = new JButton("Load Data");
JButton loginButton = new JButton("Login");
JLabel editLabel = new JLabel("Write:");
JTextArea editArea = new JTextArea();
public GUI()
{
Toolkit theKit = aWindow.getToolkit();
Dimension wndSize = theKit.getScreenSize();
aWindow.setBounds(wndSize.width/3, wndSize.height/3, 250, 250);
aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridLayout grid = new GridLayout(1,1);
Container content = aWindow.getContentPane();
content.setLayout(grid);
createLoginPanel();
createDisplayPanel();
createEditPanel();
myTabs.addTab("Login", loginMainPanel);
myTabs.addTab("Main Menu", displayMainPanel);
myTabs.addTab("Setting", editMainPanel);
myTabs.setSelectedIndex(0);
myTabs.setEnabledAt(1,false);
myTabs.setEnabledAt(2,false);
content.add(myTabs);
aWindow.setVisible(true);
}
public void createLoginPanel()
{
loginMainPanel.setLayout(null);
loginLabel.setBounds(10, 15, 150, 20);
loginMainPanel.add(loginLabel);
loginField.setBounds(10, 35, 150, 20);
loginMainPanel.add(loginField);
loginLabel2.setBounds(10, 60, 150, 20);
loginMainPanel.add(loginLabel2);
loginPass.setBounds(10, 80, 150, 20);
loginMainPanel.add(loginPass);
loginButton.addActionListener(this);
loginButton.setBounds(50, 110, 80, 20);
loginMainPanel.add(loginButton);
}
public void createDisplayPanel()
{
displayMainPanel.setLayout(null);
displayButton.addActionListener(this);
displayButton.setBounds(50, 80, 150, 20);
displayMainPanel.add(displayButton);
myText1.setBounds(50, 170, 200, 30);
myText2.setBounds(50, 140, 200, 30);
myText3.setBounds(50, 110, 200, 30);
displayMainPanel.add(myText1);
displayMainPanel.add(myText2);
displayMainPanel.add(myText3);
}
public void createEditPanel()
{
editMainPanel.setLayout(null);
editLabel.setBounds(10, 15, 150, 20);
editMainPanel.add(editLabel);
editArea.setBounds(10, 65, 150, 50);
editMainPanel.add(editArea);
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == loginButton)
{
//myTabs.setSelectedIndex(1);
}
}
public void paint(Graphics g) {
super.paint(g);
int locX = 0;
int locY = 0;
int destX = 210;
int destY = 210;
g.setColor(Color.red);
// draw a line (there is now drawPoint..)
g.drawLine(locX, locY, destX, destY);
}
public static void main(String[] args)
{
GUI tw1 = new GUI();
}
}
How can I find a solution so it will paint that line on the tab (loginMainPanel)?

If you want custom drawing on a JPanel, you should create a custom class that extends JPanel:
class CustomPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(x1, y1, x2, y2);
}
}
Then:
JPanel loginMainPanel = new JPanel();
Woudl become:
JPanel loginMainPanel = new CustomPanel();

Sorry for the blurge of bloated code
Yes, well that is why people can't solve problems, because the code is so bloated you can't see what you are doing.
If you want us to help you problem solve then you need to post a SSCCE
Someone told me a way to paint onto a Jframe
Well, that is wrong, in general you should not be overrding the paint() method, unless you have a specific reason.
Also, your whole program is wrong because you are extending JTabbedPane. You should never do this to create a GUI.
Your paint() method is never invoked because you never use that class anywhere. Look at your code. For your class variables you create a new JTabbedPane. Then in the constructor you add all these components to the frame and make the frame visible.
You need to take a look at the Swing tutorial and follow some of the example there for a better way to create a simple GUI.
I don't understand what you are trying to do by drawing a line on the tabbed pane. A tabbed pane displays different panels every time you click on a tab. Where exactly do you want the line to appear?
Also, you should learn how to use layout managers. Using a null layout will cause unnecessary problems.
Until you post a SSCCE, I can't be of much help.

Related

Panel components moves after rolling up the frame

I have such code, where I need to create some buttoms for customizing the square. It works, but after rolling up the frame the text field moves all over the frame and I don't know why. I mean when I execute the programm for first it's located in the right position that I mentioned using method setBounds(), but then it's located above the square. So how can I fix it?
import java.awt.*;
import java.awt.event.*;
import java.text.AttributedString;
import javax.swing.*;
import java.awt.font.TextAttribute;
public class Square extends JFrame implements ActionListener {
Button butt1 = new Button("Fill with yellow");
Button butt2 = new Button("Fill with red");
Button butt3 = new Button("Add label");
Button butt4 = new Button("");
Pan contentPane = new Pan();
public Square() {
super("Square");
this.setBounds(200, 100, 670, 400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().add(contentPane);
contentPane.setBounds(0, 0, 670, 275);
contentPane.setBackground(Color.BLACK);
add(butt1);
butt1.setBounds(25, 300, 190, 25);
butt1.addActionListener(this);
add(butt2);
butt2.setBounds(235, 300, 190, 25);
butt2.addActionListener(this);
butt3.setBounds(440, 300, 190, 25);
butt3.addActionListener(this);
add(butt3);
add(butt4);
}
#Override
public void actionPerformed(ActionEvent e) {
Object o = e.getSource();
if (o == butt1) {
contentPane.draw(1);
}
else if (o == butt2) {
contentPane.draw(2);
}
else if (o == butt3) {
contentPane.draw(3);
}
}
public static void main(String[] args) {
Square w = new Square();
w.setVisible(true);
}
}
class Pan extends JPanel {
Graphics g;
Graphics2D g2;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.GRAY);
g.drawRect(240, 70, 150, 150);
}
public void draw(int i) {
g = getGraphics();
super.paintComponent(g);
g2 = (Graphics2D) g.create();
switch(i) {
case 1: g2.setColor(Color.yellow);
g2.fillRect(240, 70, 150, 150);
break;
case 2: g2.setColor(Color.red);
g2.fillRect(240, 70, 150, 150);
break;
case 3:
g.setColor(Color.GRAY);
g.drawRect(240, 70, 150, 150);
JTextField text = new JTextField(25);
this.add(text);
Button add = new Button("Add");
add.setBounds(400, 230, 120, 25);
this.add(add);
text.setBounds(240, 230, 150, 25);
Font font = new Font("Veranda", Font.BOLD|Font.ITALIC, 24);
class AddButton extends JPanel implements ActionListener {
#Override
public void actionPerformed(ActionEvent ev) {
AttributedString label = new AttributedString(text.getText());
label.addAttribute(TextAttribute.FONT, font);
label.addAttribute(TextAttribute.FOREGROUND, Color.PINK);
g2.drawString(label.getIterator(), 240, 50);
}
}
AddButton listener = new AddButton();
add.addActionListener(listener);
break;
}
}
}
Okay lots of core issues and misunderstandings.
Swing uses layout managers. This is probably one of the first things you're butting heads again. Layout managers make decisions about how best to position components based on their individual algorithms.
Start by taking a look at Laying Out Components Within a Container for more details and make good use of them. GUIs are complex and dynamic things, with many factors going in to determining how components should be sized and positioned.
Painting. Another problem new developers have is understanding that they don't control the paint system. Swing uses a passive rendering system, which means it will paint when it feels its required.
You can provide hints when a new paint pass should be done by calling repaint, but it's up to the system to decide what and when something should be painted.
g = getGraphics(); is a bad idea on many levels. Apart from been able to return null, it's nothing more then a snapshot of the last paint pass and will be discarded when a new paint pass occurs.
Calling super.paintComponent(g); outside of a paint pass is also a bad idea. In fact, there should rarely ever be a need to call any of the paint methods directly.
This is NOT how custom painting should be done. Start by having a look at Performing Custom Painting and Painting in AWT and Swing for how painting works and how you should work with it
Also, mixing heavy weight (AWT) and light weight (Swing) components together is generally a bad idea should be avoid as much as possible.
Example...
So, I "hacked" you example into something a "little" more reasonable
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class Square extends JFrame implements ActionListener {
JButton butt1 = new JButton("Fill with yellow");
JButton butt2 = new JButton("Fill with red");
JButton butt3 = new JButton("Add label");
JButton butt4 = new JButton("");
Pan contentPane = new Pan();
public Square() {
super("Square");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().add(contentPane);
contentPane.setBackground(Color.BLACK);
JPanel actions = new JPanel();
actions.setBorder(new EmptyBorder(10, 10, 10, 10));
actions.add(butt1);
butt1.addActionListener(this);
actions.add(butt2);
butt2.addActionListener(this);
butt3.addActionListener(this);
actions.add(butt3);
// actions.add(butt4);
add(actions, BorderLayout.SOUTH);
pack();
setLocationRelativeTo(null);
}
#Override
public void actionPerformed(ActionEvent e) {
Object o = e.getSource();
if (o == butt1) {
contentPane.draw(1);
} else if (o == butt2) {
contentPane.draw(2);
} else if (o == butt3) {
contentPane.draw(3);
}
}
public static void main(String[] args) {
Square w = new Square();
w.setVisible(true);
}
}
class Pan extends JPanel {
private int state = -1;
private String text = null;
public Pan() {
Font font = new Font("Veranda", Font.BOLD | Font.ITALIC, 24);
setFont(font);
setLayout(new GridBagLayout());
setBorder(new EmptyBorder(10, 10, 10, 10));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(670, 275);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(Color.GRAY);
g2.drawRect(240, 70, 150, 150);
switch (state) {
case 1:
g2.setColor(Color.yellow);
g2.fillRect(240, 70, 150, 150);
break;
case 2:
g2.setColor(Color.red);
g2.fillRect(240, 70, 150, 150);
break;
case 3:
g.setColor(Color.GRAY);
g.drawRect(240, 70, 150, 150);
break;
}
if (text != null) {
AttributedString label = new AttributedString(text);
label.addAttribute(TextAttribute.FONT, getFont());
label.addAttribute(TextAttribute.FOREGROUND, Color.PINK);
g2.drawString(label.getIterator(), 240, 50);
}
}
public void draw(int i) {
switch (i) {
case 3:
JTextField textField = new JTextField(25);
JButton add = new JButton("Add");
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weighty = 1;
gbc.anchor = GridBagConstraints.SOUTH;
this.add(textField, gbc);
gbc.gridx++;
this.add(add, gbc);
add.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ev) {
text = textField.getText();
remove(textField);
remove(add);
revalidate();
repaint();
}
});
revalidate();
repaint();
break;
}
state = i;
repaint();
}
}
Your code is full of, what is commonly known as, "magic numbers". These are values whose meaning is unknown.
Run the code and try resizing the window and you will see what I mean. Instead, you should be relying on "known" values, like getWidth and getHeight to make better determinations about how you should render the output

How to add an image at specific location in JFrame in Java using eclipse?

I have made a student information page using GUI concept. I want to know that how can i add an image at a specific location using JLabel or any other method? What i want is a background image surrounding the whole Jframe and another image at specific location like at the top right. How can i achieve this?
i also found a code to add image using Jlabel but it doesn't work with my code as my setting the layout to null.
the code i found
String path = "Image1.jpg";
File file = new File(path);
BufferedImage image = ImageIO.read(file);
JLabel label = new JLabel(new ImageIcon(image));
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(label);
f.pack();
f.setLocation(200,200);
f.setVisible(true);
Below is my code:
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class LoginPage
{
JFrame jf;
JLabel gender,hobbies,name_label,rollno_label,marks_label,city_label,address_label;
JTextField name_field,rollno_field,marks_field;
JRadioButton male,female;
ButtonGroup bg;
JCheckBox photography,music,sketching,coding;
JComboBox city_combo;
JTextArea adress_textarea;
JButton save, exit;
JMenuBar mbar;
JMenu file,edit,help;
JMenuItem open,save_item,edit_item,close,cut,copy,paste,find,replace,help_content,about,updates;
public LoginPage() //constructor
{
jf = new JFrame("Student Information");
name_label = new JLabel("Student's Name");
name_field = new JTextField();
rollno_label = new JLabel("Student's Roll Number");
rollno_field = new JTextField();
marks_label = new JLabel("Student's Total Marks Achieved");
marks_field = new JTextField();
gender = new JLabel("Gender");
male = new JRadioButton("Male");
female = new JRadioButton("Female");
bg = new ButtonGroup();
hobbies = new JLabel("Hobbies");
photography = new JCheckBox("Photography");
music = new JCheckBox("Music");
coding = new JCheckBox("Coding");
sketching = new JCheckBox("Sketching");
city_label = new JLabel("City");
city_combo = new JComboBox();
address_label = new JLabel("Residential Address");
adress_textarea = new JTextArea();
save = new JButton("Save");
exit = new JButton("Exit");
mbar = new JMenuBar();
file = new JMenu("File");
edit = new JMenu("Edit");
help = new JMenu("Help");
open = new JMenuItem("open");
save_item = new JMenuItem("Save");
edit_item = new JMenuItem("Edit");
close = new JMenuItem("Close");
cut = new JMenuItem("Cut");
copy = new JMenuItem("Copy");
paste = new JMenuItem("Paste");
find = new JMenuItem("Find");
replace = new JMenuItem("Replace");
about = new JMenuItem("About");
updates = new JMenuItem("Check for Updates");
help_content = new JMenuItem("Help Content");
}
void Display()
{
jf.setSize(1000, 700);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLayout(null);
jf.getContentPane().setBackground( Color.LIGHT_GRAY );
name_label.setBounds(50, 50, 150, 20);
name_field.setBounds(300, 50, 200, 20);
rollno_label.setBounds(50, 100, 150, 20);
rollno_field.setBounds(300, 100, 200, 20);
marks_label.setBounds(50, 150, 200, 20);
marks_field.setBounds(300, 150, 200, 20);
gender.setBounds(50, 200, 100, 20);
male.setBounds(300, 200, 80, 20);
female.setBounds(400, 200, 80, 20);
hobbies.setBounds(50, 250, 80, 20);
photography.setBounds(300, 250, 100, 20);
music.setBounds(420, 250, 80, 20);
sketching.setBounds(500, 250, 100, 20);
coding.setBounds(600, 250, 80, 20);
city_label.setBounds(50, 300, 100, 20);
city_combo.setBounds(300, 300, 100, 20);
address_label.setBounds(50, 350, 200, 20);
adress_textarea.setBounds(300, 350, 300, 100);
save.setBounds(300, 500, 100, 50);
exit.setBounds(600, 500, 100, 50);
bg.add(male);
bg.add(female);
city_combo.addItem("Select City");
city_combo.addItem("Chandigarh");
city_combo.addItem("Kurali");
city_combo.addItem("Mohali");
city_combo.addItem("Panchkula");
file.add(open);
file.add(save_item);
file.add(edit_item);
file.add(close);
edit.add(cut);
edit.add(copy);
edit.add(paste);
edit.add(find);
edit.add(replace);
help.add(about);
help.add(help_content);
help.add(updates);
mbar.add(file);
mbar.add(edit);
mbar.add(help);
jf.add(name_label);
jf.add(name_field);
jf.add(rollno_label);
jf.add(rollno_field);
jf.add(marks_label);
jf.add(marks_field);
jf.add(gender);
jf.add(male);
jf.add(female);
jf.add(hobbies);
jf.add(music);
jf.add(photography);
jf.add(sketching);
jf.add(coding);
jf.add(city_label);
jf.add(city_combo);
jf.add(address_label);
jf.add(adress_textarea);
jf.add(save);
jf.add(exit);
jf.setJMenuBar(mbar);
jf.setVisible(true);
}
public static void main(String[] args) {
new LoginPage().Display();
}
}
What i want is a background image surrounding the whole Jframe
Suggestions:
Create a class that extends JPanel,
override its paintComponent method
be sure to call the super's paintComponent method in your override
Draw your background image within this method using g.drawImage(...)
Either make this JPanel your JFrame's contentPane or add it to the contentPane BorderLayout.CENTER, and then add your GUI components to this JPanel
Make sure that some of the components are not-opaque, e.g., call setOpaque(false) on your JRadioButtons, and perhaps others, so that the background image shows up.
and another image at specific location like at the top right. How can i achieve this?
Use the same JPanel above, and draw the smaller image using an overload of drawImage(...) that precisely places the image where you want
Notes:
When I create background images for the GUI, I prefer to draw within a JPanel rather than a JLabel since the JLabel is not wired out of the box to act as a contentPane or a decent container.
I strongly advise you not to use null layouts and setBounds as this will lead to gui's that might look good on one platform, but not on another, that have JLabels whose text is not fully seen, that are very difficult to upgrade and maintain. Learn and use the layout managers.
Looks like you're using multiple JFrames. If so, please read: The Use of Multiple JFrames: Good or Bad Practice?
For example, here's one way to display an image as a background image as well as a smaller image in the right upper portion of the GUI, all within a JPanel:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class LoginPage3 extends JPanel {
public static final String BG_IMG_PATH = "https://upload.wikimedia.org/wikipedia/"
+ "commons/e/e9/Maesil_%28prunus_mume%29_washed_and_stemmed.jpg";
public static final String RU_IMG_PATH = "https://upload.wikimedia.org/wikipedia/"
+ "commons/thumb/5/5b/Escudo_de_San_Pedro_de_Atacama.svg/200px-Escudo_de_San_Pedro_de_Atacama.svg.png";
private BufferedImage backgroundImg;
private BufferedImage rightUpperImg;
public LoginPage3(BufferedImage bgImg, BufferedImage ruImg) {
this.backgroundImg = bgImg;
this.rightUpperImg = ruImg;
}
#Override
public Dimension getPreferredSize() {
if (backgroundImg == null || isPreferredSizeSet()) {
return super.getPreferredSize();
} else {
int w = backgroundImg.getWidth();
int h = backgroundImg.getHeight();
return new Dimension(w, h);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (backgroundImg != null) {
g.drawImage(backgroundImg, 0, 0, this);
}
if (rightUpperImg != null) {
int x = getWidth() - rightUpperImg.getWidth();
g.drawImage(rightUpperImg, x, 0, this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
BufferedImage bg = null;
BufferedImage ru = null;
try {
bg = ImageIO.read(new URL(BG_IMG_PATH));
ru = ImageIO.read(new URL(RU_IMG_PATH));
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
LoginPage3 mainPanel = new LoginPage3(bg, ru);
JFrame frame = new JFrame("LoginPage3");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
For background image:
Load it as an icon, and create a JLabel with it. (See your first snippet)
Set the JLabel as the JFrame's content pane.
All you have to take care of, that Icon does not stretch, so you have to have an image that is exactly the same size as your JFrame (or larger).
As for the image at a given position, the JLabel creating and Icon loading process is the same, but after adding it to the JFrame you have to set position and size, just like for your other components, EG call setBounds()...

swing - why is this creating two separate boxes

I apologise now if my terminology or turns of phrase aren't right, I'm new to swing. Also, apologise for the clunky and intelligent way I've tried to get this to work.
I am trying to create a single box that has a JTextArea inside it, and next this this area (still in the same box), has some buttons. However, all I've managed to do is make a box with the buttons in, and a separate box with a text area.
I have looked at many examples where people are trying to do similar things and I thought I managed to understand and implement it, but I haven't yet succeeded. If someone could point me at the part(s) of the code I'm misunderstanding I would be very grateful.
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.*;
public class GameGUI extends JFrame implements ActionListener
{
private static final long serialVersionUID = 1L;
JPanel panel = new JPanel();
JTextArea textArea = new JTextArea(50, 50);
JScrollPane scrollPane = new JScrollPane(textArea);
String action;
private static GUIClient client = new GUIClient();
JButton n = new JButton("N");
JButton e = new JButton("E");
JButton s = new JButton("S");
JButton w = new JButton("W");
JButton look = new JButton("LOOK");
JButton pickup = new JButton("PICKUP");
JButton hello = new JButton("HELLO");
JButton quit = new JButton("QUIT");
public GameGUI()
{
textArea.setEditable(false);
panel.add(new JScrollPane(textArea));
this.setBounds(300, 300, 750, 500);
this.setVisible(true);
this.setResizable(false);
this.setLayout(null);
n.setBounds(225, 25, 50, 50);
e.setBounds(300, 100, 50, 50);
s.setBounds(225, 175, 50, 50);
w.setBounds(150, 100, 50, 50);
look.setBounds(50, 362, 100, 50);
pickup.setBounds(200, 362, 100, 50);
hello.setBounds(350, 362, 100, 50);
quit.setBounds(500, 362, 100, 50);
this.add(n);
this.add(e);
this.add(s);
this.add(w);
this.add(look);
this.add(pickup);
this.add(hello);
this.add(quit);
n.addActionListener(this);
e.addActionListener(this);
s.addActionListener(this);
w.addActionListener(this);
look.addActionListener(this);
pickup.addActionListener(this);
hello.addActionListener(this);
quit.addActionListener(this);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.pack();
this.setVisible(true);
}
public void displayInGUI(String fromServer)
{
textArea.append(fromServer);
textArea.setCaretPosition(textArea.getDocument().getLength());
}
public void actionPerformed(ActionEvent f)
{
if(f.getSource()==n)
{
action = "MOVE N";
client.display(action);
}
else if(f.getSource()==e)
{
action = "MOVE E";
client.display(action);
}
else if(f.getSource()==s)
{
action = "MOVE S";
client.display(action);
}
else if(f.getSource()==w)
{
action = "MOVE W";
client.display(action);
}
else if(f.getSource()==look)
{
action = "LOOK";
client.display(action);
}
else if(f.getSource()==pickup)
{
action = "PICKUP";
client.display(action);
}
else if(f.getSource()==hello)
{
action = "HELLO";
client.display(action);
}
else if(f.getSource()==quit)
{
action = "QUIT";
client.display(action);
}
}
}
I've used this class by creating an instance of it in GUIClient (I've also created an instance of GUIClient in this class, GameGUI, which seems really ugly but it was the only way I could think to notice when the buttons were pressed).
So, if I want to run the game, I set up the server, then run GUIClient, which creates the two boxes. GUIGame then notices when the buttons are pressed and sends this info to the client which sends it to the server.
Again, I'm sorry this is so convoluted. I hope my explanation helped clear things up but if not just let me know.
Many thanks,
Elise.
I added a 'main()' method (and commented out the client parts) so I could run your program. I also set the Frame's size to 800x500 so it is visible. This is what I see:
The reason the text area is not visible is you did not add it to the frame. You will need to add the panel that contains the scrollpane that contains the textarea to the frame. You will also need to position and size it. For example:
panel.setBounds(400, 25, 200, 200);
this.add(panel);
This produces the following:

How do I implement ActionListener inside a JPanel class that's inside another class?

I have a class called 'Panel' that extends JPanel and it is inside another class called 'Main'. The constructor instantiates JFrame, and all the GUI components, and sets it all up, such as size.
The class 'Panel' which extends JPanel has a method public void paintComponent(Graphics g){} and inside it I added a few JButtons and used g.drawString's.
Then in the 'Main' class, I added the 'Panel' to the JFrame.
My question is, I am trying to implement an actionListener to a button added inside the 'Panel' class. The actionListener function would add more buttons and use g.drawString's as well. Now where would I place the ActionListener in order to do so? How can I use g.drawString for a particular panel and the g.drawString line is inside another class, which is the ActionListener class? I would need to use Graphics g of paintComponent inside the actionPerformed.
Thank you!
EDIT -
CODE EXAMPLE:
public class Main{
private JFrame jf;
private JTextField jtf1;
private JTextField jtf2;
private Panel p;
private JComboBox jcb1;
private JComboBox jcb2;
private JButton button;
private Object options[];
//ActionListener Variables
private int string1 = 150;
private int string2 = 150;
private int yJtf1 = 150;
private int yJtf2 = 160;
private int cb1 = 140;
private int cb2 = 165;
private int count = 0;
public Main(){
jf= new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(700, 700);
p = new Panel();
jtf1 = new JTextField("", 20);
jtf2= new JTextField("", 20);
Object options[] = {""};
jcb1 = new JComboBox(tools);
jcb2 = new JComboBox(tools);
button = new JButton("+");
jf.add(p);
jf.setVisible(true);`
}
public class Panel extends JPanel{
public Panel(){
this.setLayout(null);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
/*button.addActionListener(new ActionListener(){ //Would this work or should the ActionListener be a class as shown below?
public void actionPerformed(ActionEvent e){
if(count < 3){ //Won't be allowed to add anymore after 3 times
string1 += 50;
string2 += 50;
jtf1 += 50;
jtf2 += 50;
cb1 += 50;
cb2 += 45;
//Would like to add the following components to the 'Panel' (which is a JPanel) whenever the JButton 'button' already added to 'Panel' is clicked.
p.add(jtf1); //Would doing p.add really add to the panel when the ActionListener is called?
jtf1.setBounds(60, yJtf1, 50, 40);
p.add(jtf2);
jtf2.setBounds(60, yJtf2, 50, 40);
add(jcb1);
jcb1.setBounds(250, cb1, 50, 40);
add(left2);
jcb2.setBounds(250, cb2, 50, 40);
Font font = new Font("TimesRoman", Font.BOLD, 18);
g.setFont(font); //Getting error on 'g' regardless
g.drawString("Hi", 15, string1); //This is the main problem, how would I be able to add this strings to the 'Panel' (which is a JPanel)
g.drawString("There", 330, string1);
}
count++;
}
});*/
add(jtf1);
jtf1.setBounds(100, 30, 120, 30);
add(jtf2);
ljtf2.setBounds(100, 60, 120, 30);
add(button);
plusButton.setBounds(200,150, 50, 50);
//button.addActionListener(new ButtonClicked()); if doing ActionListener via class like below
add(jcb1);
jcb1.setBounds(300, 350, 100, 50);
add(ljcb2);
jcb2.setBounds(300, 350, 100, 25);
Font font = new Font("Arial", Font.BOLD, 12);
g.setFont(font);
g.drawString("Item:", 40, 45);
g.drawString("Cost:", 40, 75);
}
}
public static void main(String [] args){
new Main();
}
class ButtonClicked implements ActionListener{ //Action Listener: The follow is what I am trying to implement
public void actionPerformed(ActionEvent ae){
if(count < 3){ //Won't be allowed to add anymore after 3 times
string1 += 50;
string2 += 50;
jtf1 += 50;
jtf2 += 50;
cb1 += 50;
cb2 += 45;
//Would like to add the following components to the 'Panel' (which is a JPanel) whenever the JButton 'button' already added to 'Panel' is clicked.
p.add(jtf1); //Would doing p.add really add to the panel when the ActionListener is called?
jtf1.setBounds(60, yJtf1, 50, 40);
p.add(jtf2);
jtf2.setBounds(60, yJtf2, 50, 40);
mp.add(jcb1);
jcb1.setBounds(250, cb1, 50, 40);
mp.add(left2);
jcb2.setBounds(250, cb2, 50, 40);
Font font = new Font("TimesRoman", Font.BOLD, 18);
g.setFont(font);
g.drawString("Hi", 15, string1); //This is the main problem, how would I be able to add this strings to the 'Panel' (which is a JPanel)
g.drawString("There", 330, string1);
}
count++;
}
}
}
I would need to use Graphics g of paintComponent inside the actionPerformed."`
No, you wouldn't since Swing graphics is passive not active. The Graphics object would reside in the JPanel's paintComponent method and would be passed to it from the JVM when it and only it calls the paintComponent method. The actionPerformed method would then change the value of a String variable or perhaps an ArrayList<String>, call repaint(), and then the JPanel's paintComponent method would use the changed String to draw the appropriate text.
If you need more specific help, consider telling us a few more details and posting a minimal example program.
Edit
On review of your code I have several suggestions:
Please try to fix your code a bit so that it is either compilable or as close to compilable as possible.
Never add components or do anything but painting inside of your paintComopnent(...) method. You don't have full control over when or even if that method will be called, and placing something in inside of this method will result in unwanted side effects, like combo boxes that simply won't work.
If you ever wanted text shown in your program, you can always add a JLabel.
Your program uses null layout and setBounds(...) something that results in a rigid GUI that may look good on one system but will usually look poor on any other system or screen resolution. Also programs created this way are very hard to debug, maintain and upgrade. Instead use the layout managers as this is what they excel at: at creating complex flexible GUI's that can be enhanced and changed easily.
Edit
I'm guessing what you really want to do, and that possibly is to add more components to allow the user to enter more data into the GUI. You also want to add text perhaps to guide the user in what the purpose of the components may be. If this is so, then the best solution is not to add Strings to the GUI in paintComponent but rather to add Strings/Components in an organized fashion with the Strings being displayed in JLabels, and the components and the labels all held in a JPanel or JPanels, and added to the GUI using layout managers.
For example, if you want the user to add data in two JTextfields and have two JComboBoxes, and then allow the user to add 3 more of these guys if need be, a GUI could look something like this:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class Main2 extends JPanel {
private List<DataPanel> dataPanelList = new ArrayList<>();
private JPanel dataPanelHolder = new JPanel();
public Main2() {
DataPanel dataPanel = new DataPanel();
dataPanelList.add(dataPanel);
setLayout(new BorderLayout());
dataPanelHolder.setLayout(new BoxLayout(dataPanelHolder, BoxLayout.PAGE_AXIS));
dataPanelHolder.add(dataPanel);
JPanel innerBorderLayoutPanel = new JPanel(new BorderLayout());
innerBorderLayoutPanel.add(dataPanelHolder, BorderLayout.PAGE_START);
JScrollPane scrollPane = new JScrollPane(innerBorderLayoutPanel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
int w = dataPanel.getPreferredSize().width;
int h = dataPanel.getPreferredSize().height * 4;
Dimension viewPortSize = new Dimension(w, h);
scrollPane.getViewport().setPreferredSize(viewPortSize);
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));
buttonPanel.add(new JButton(new AddDatatAction("Add")));
buttonPanel.add(new JButton(new ExitAction("Exit", KeyEvent.VK_X)));
add(scrollPane, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.PAGE_END);
}
private class AddDatatAction extends AbstractAction {
private int maxCount = 4;
public AddDatatAction(String name) {
super(name);
int mnemonic = (int)name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
if (dataPanelList.size() < maxCount) {
DataPanel dataPanel = new DataPanel();
dataPanelList.add(dataPanel);
dataPanelHolder.add(dataPanel);
dataPanelHolder.revalidate();
dataPanelHolder.repaint();
}
}
}
private class ExitAction extends AbstractAction {
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Window win = SwingUtilities.getWindowAncestor(Main2.this);
win.dispose();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Main2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Main2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class DataPanel extends JPanel {
private static final String[] TOOLS = {"Tool 1", "Tool 2", "Tool 3", "Tool 4"};
private static final String[] FIELD_LABELS = {"Item", "Cost"};
private static final String[] COMBO_LABELS = {"Foo", "Bar"};
private JTextField[] fields = new JTextField[FIELD_LABELS.length];
private List<JComboBox<String>> comboList = new ArrayList<>();
public DataPanel() {
setBorder(BorderFactory.createTitledBorder("Data"));
setLayout(new GridBagLayout());
for (int i = 0; i < FIELD_LABELS.length; i++) {
add(new JLabel(FIELD_LABELS[i]), createGbc(0, i));
fields[i] = new JTextField(10);
add(fields[i], createGbc(1, i));
JComboBox<String> combo = new JComboBox<>(TOOLS);
comboList.add(combo);
add(combo, createGbc(2, i));
add(new JLabel(COMBO_LABELS[i]), createGbc(3, i));
}
}
public static GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
int ins = 4;
gbc.insets = new Insets(ins, ins, ins, ins);
return gbc;
}
}
And could look like:
one datapanel added
four added:

java swing design to create a textfield

I want to create a jtext field with a definite size, but I would like it to expand like a scroll pane when the input grows. Here is what I have so far:
JButton b,b1;
JLabel j1,j2,j3;
JTextField t1,t2;
public Window(){
super("frame");
//new Thread(this).start();
b=new JButton("Click");
j1=new JLabel("VALUE1");
t1=new JTextField(30);
j2=new JLabel("VALUE2");j3=new JLabel(" ");
t2=new JTextField(30);
j1.setBounds(100, 50, 150, 50);
t1.setBounds(150, 50, 200, 50);
j2.setBounds(200, 150, 250, 150);
t2.setBounds(250, 150, 200, 50);j3.setBounds(300, 150, 250, 150);
b.setBorder(new LineBorder(Color.black));
b.setBackground(Color.black);
b.setForeground(Color.white);
b1=new JButton("Exit");
super.setSize(300,300);
super.setLocation(250,150);
super.setLayout(new FlowLayout());
super.setVisible(true);
add(j1);add(t1);add(j2);add(t2); add(j3);
add(b);add(b1);
b.addActionListener(this);
b1.addActionListener(this);
If you dont want to use JScrollPane this is something you are looking for -
I have created a sample program to auto resize the JTextField size
i.e if text is added its size increases and if text is deleted its size is reduced.
I have used KeyListener's - keyTyped event to detect and update the text field size.
You can add document listener too to do the same thing.
Here is my sample code -
import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class AutoResizeTest
{
public AutoResizeTest(){
JFrame frame = new JFrame("Auto-Resizable TextField");
frame.setLayout(null);
MyCustomTextField expandableText = new MyCustomTextField(20);
expandableText.setBounds(10, 10, 200, 30);
expandableText.setPreferredSize(new Dimension(200,30));
expandableText.setMaximumSize(new Dimension(600,30));
frame.add(expandableText);
frame.setBounds(100,100,700,100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args)
{
AutoResizeTest test = new AutoResizeTest();
}
class MyCustomTextField extends javax.swing.JTextField{
private int originallimit;
int previousLength;
int length;
public MyCustomTextField(int limit){
previousLength=0;
originallimit = limit;
this.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
JTextField textField = (JTextField) e.getSource();
length = textField.getText().length();
if(length >= originallimit){
if(length > previousLength){
textField.setSize(new Dimension(textField.getWidth()+10, textField.getHeight()));
}
else{
if(length < previousLength)
textField.setSize(new Dimension(textField.getWidth()-10, textField.getHeight()));
}
previousLength = length;
}else{
textField.setSize(textField.getPreferredSize());
}
}
});
}
}
}
In this code I have increamented/reduced the size by 10. You can put your desired value.
Hope that helps you.
Place the TextArea in a seperate JPanel with BorderLayout and in the center and the panel automatically expands, when the content increases.
textArea = new JTextArea(2, WIDTH);
textArea.setLineWrap(true);
textArea.getDocument().putProperty("filterNewlines", Boolean.TRUE);
The default size of the JTextField will be set and provide a ScrollPane to JTextField which will make field to expand if necessary.
Try the following
JTextField jtext = new JTextField(pane);
JScrollPane scroll = new JScrollPane(jtext);

Categories

Resources