Java Component With JPanel - java

I am trying to create a JFrame in Java, with a JPanel inside of it, which will hold a component.
I know how to add components using
panelname.add(component);
But I am making a class based off a JTextField and want to add the entire CLASS as a component into the JPanel, but when I do, Eclipse tells me:
The method add(Component) in the type Container is not applicable for the arguments (BetterText)
(BetterText been the name of the class)
So all it basically is, is a class with a JTextField setup with methods and such, but I want to add that class as a component to the JPanel. I looked at the JTextField.java class and cant see anything interesting there, it looks like an ordinary class like any other, but you are able to add an instance of that class to a JPanel, whereas with mine, you cant.
Any help will be appreciated, thankyou.
Also, if you know the solution, please post an example class.
Edit: Added code.
public BetterText(String defaultText) {
super();
//Sets up the textFields colours and the defaultText to display in it.
setProperties();
hasDefault = true;
this.defaultText = defaultText;
textField.addActionListener(this);
}
Another edit:
It also extends JTextField already.
public class BetterText extends JTextField implements ActionListener {

Make sure your JFrame, JPanel and JTextField extend the correct classes (if they are custom classes).
Some pseudo code:
public class BetterText() extends JTextField{
public BetterText(){
super();
}
}
And then to create the GUI:
JFrame frame = new JFrame();
JPanel panel = new JPanel();
BetterText textField = new BetterText();
frame.add(panel);
panel.add(textField);
panel.pack();
panel.setVisible(true);

Verify that you are importing javax.swing.JComponent, then make your BetterText class inherit from JTextField.

Related

Adding a JPanel created from class to JtabbedPane

I'm trying to add a JPanel to a tab.
The panel is created with the LanguageTab class but I can't figure out why it doesn't work.
It maybe stupid but self taught is not enough here.
Hope someone can give me a little hand. thanks!
I have my code down here for you to understand what I'm going through!
public class MainTab extends JPanel {
JTabbedPane mainTab;
JPanel languageTab;
JFrame mainFrame;
JPanel mainPanel;
public MainTab(){
mainFrame = new JFrame();
mainTab = new JTabbedPane();
mainPanel = new JPanel();
//mainPanel.add(new JTextField("ciao"));
mainPanel.add(new JLabel(new ImageIcon("C:\\Users\\angelica\\Desktop\\developed.jpg")));
//languageTab = new LanguageTab();
mainTab.add("main",mainPanel);
mainTab.add("Language Tab",languageTab);
add(mainTab);
mainFrame.add(mainTab);
mainFrame.setVisible(true);
mainFrame.setDefaultLookAndFeelDecorated(true);
}
public static void main(String args[]){
MainTab mt = new MainTab();
}
}
and this is my LanguageTab
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
public class LanguageTab extends JPanel implements ActionListener{
public LanguageTab(){
ImageIcon icona = new ImageIcon("C:\\Users\\angelica\\workspace\\whatever\\src\\whatever\\ita.jpg");
ImageIcon icona_DSA = new ImageIcon("C:\\Users\\angelica\\workspace\\whatever\\src\\whatever\\ita2.jpg");
ImageIcon iconb = new ImageIcon("C:\\Users\\angelica\\workspace\\whatever\\src\\whatever\\brit.jpg");
ImageIcon iconb_DSA =new ImageIcon("C:\\Users\\angelica\\workspace\\whatever\\src\\whatever\\brit2.jpg");
JPanel langTab= new JPanel();
langTab.setLayout(new GridLayout(2,2));
JButton ADHDbutton = new JButton("ADHD ENGLISH");
ADHDbutton.setIcon(iconb);
ADHDbutton.setActionCommand("adhd_english");
ADHDbutton.addActionListener(this);
JButton ADHDbutton1 = new JButton("ADHD \n ITALIANO");
ADHDbutton1.setIcon(icona);
ADHDbutton1.setActionCommand("adhd_italiano");
ADHDbutton1.addActionListener(this);
JButton DSAbutton = new JButton("DSA ENGLISH");
DSAbutton.setIcon(iconb_DSA);
DSAbutton.setActionCommand("dsa_english");
DSAbutton.addActionListener(this);
JButton DSAbutton1 = new JButton("DSA ITALIANO");
DSAbutton1.setIcon(icona_DSA);
DSAbutton1.setActionCommand("dsa_italiano");
DSAbutton1.addActionListener(this);
langTab.add(ADHDbutton);
langTab.add(ADHDbutton1);
langTab.add(DSAbutton);
langTab.add(DSAbutton1);
//return toModify;
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
You need to set the size of your JFrame so that it's large enough to see its contents.
Add the following as the last line of your MainTab constructor:
mainFrame.setSize(new Dimension(300, 300));
Additionally, inside your LanguageTab constructor, you have a variable called langTab, when the class itself (this) is supposed to represent the language tab. You then add all your buttons to langTab and never do anything with it.
Delete the variable langTab replace every call to it with this in the LanguageTab Constructor. Your constructor should then look something like this:
public LanguageTab() {
// button initialization goes here...
this.add(ADHDbutton);
this.add(ADHDbutton1);
this.add(DSAbutton);
this.add(DSAbutton1);
}
Now that your question has been answered, if you don't mind I would like to suggest a few things that might improve your future code quality.
Only use global variables when it's necessary to.
You declare four global variables for different parts of your UI, all of which can be declared instead as local variables. Working with Swing, it is often necessary to declare components as global so that they can be accessed in various places within the class, and that may eventually be the case for you. But you should always prefer local scoped variables when it's possible.
Give your variables the smallest possible scope
You don't have any access level (scope) modifiers on your global variables, which gives them a package scope by default. As I mentioned before it is often necessary to make swing components global for various reasons, but it is almost never necessary for them to have a scope larger than private (so they can only be accessed from within the class in which they are declared.
Access static methods in a "static way".
You call JFrame's setDefaultLookAndFeelDecorated() method using your variable mainFrame. mainFrame is an instance of the JFrame class (you declared it by saying mainFrame = new JFrame()), so you only use it to call instance methods. setDefaultLookAndFeelDecorated() is a static method (declared with the keyword static) and should therefore be accessed with the class name: JFrame.setDefaultLookAndFeelDecorated(true)
Be careful with your reference types.
You have declared your languageTab variable (in the MainTab class) as a JPanel. JPanel does not implement the ActionListener interface like your LanguageTab does, so by declaring your variable as a JPanel, you lose the ability to call actionPerformed() on it (or more likely set it as an action listener of some swing component).
Variables in Java, by convention, should begin with a lower case letter.
You gave your four buttons in the LanguageTab class names that start with capital letters. The Java convention is for variable names to begin with a lower case letter, in the same way that classes should begin with an upper case letter.

Java add a jpanel in a jtabbed pane in a jframe from another class file

I am lost, can you please help?
I am trying to add a jPanel from a another class into a different file into a JTabbedPane in JFrame file.
Here is what I have so far.
jPanel1 = new javax.swing.JPanel();
One party needs a reference to the other in some way, for example, in your "other" class, you could provide a getter method...
public class OtherClass ... {
public JPanel getComponent() {
//...
}
}
Then in your main UI, you could use the instance of OtherClass to get a reference to the JPanel...
tabbedPane.addTab("My Awesome Tab", instanceOfOtherClass.getComponent());
But this is all hypernethtical and is just one possible solution...

If I have a class that extends JPanel, should I define buttons in constructor or add() them?

So I wanted to know if it's wrong to do one of the following:
If I have a class MyJPanel extends JPanel, should I either...
a)
Write the constructor so that it adds JComponents during construction of the panel itself like this:
public MyJPanel() {
JButton button = new JButton("Hello");
JLabel labelOne = new JLabel("Hello");
JLabel labelTwo = new JLabel("Bye");
add(button);
add(labelOne);
add(labelTwo);
}
or b)
Declare these components in the class that calls MyJPanel testPanel = new MyJPanel(); and explicitly add() them? So basically:
public class SomeOtherClass {
public static void main(String[] args) {
JButton button = new JButton("Hello");
JLabel labelOne = new JLabel("Hello");
JLabel labelTwo = new JLabel("Bye");
MyJPanel testPanel = new MyJPanel();
testPanel.add(button);
testPanel.add(labelOne);
testPanel.add(labelTwo);
}
}
I know this may be a stupid question, but I just wanted to know if both are okay to do or if one of them isn't.
Consider this class a "component", that has some specific features (the buttons). That's why I think it doesn't make sense to add the features from the outside. To add the buttons in the constructor has a couple of advantages:
Reusability - you can reuse the component in other places / applications etc.
Encapsulation - the component doesn't rely on any external dependencies; this improves also testability.
Maintainability - you can easily refactor your code, by just moving this class around - no worries about any code outside of this class.
The code which you presented is just a test code, so it is hard to say how it should be designed. None of those way you presented is wrong on principle. As the rule for the real world appications you should make highly maintainable, reusable components. However the answer how you can create them depends on which level of flexibility you need. You can consider also using some factory methods which produces component in exaclty that shape you need. It is also not a bad idea to take a look how some 'default' java components are designed and implemented for example take a look at http://docs.oracle.com/javase/6/docs/api/javax/swing/JOptionPane.html.

Clarification in reaching components, Java Swing

I’m relatively new to using the javax.swing and java.awt so bear with me if I express my problem awkwardly.
Let’s say I have a custom made class CustomClass that extends and creates a JPanel p. In the class I add a JButton b to p. Later in another program file I create an instance of my CustomClass called cp and want to be able to catch for example a click event from b using the “actionPerformed” method. My question is how do I “reach” (like the written path to) the JButton b from instance cp? (Assuming that all relevant class files are already associated)
Use getters and setters if i understood correctly. I,e your customPanel will have a public getButton() method which would return the JButton instance:
class CustomPanel extends JPanel {
JButton button=new JButton("Some button");
public JButton getMyButton() {
return button;
}
}
class Test {
CustomPanel cp=new CustomPanel();
void someMethod() {
JButton b= cp.getMyButton();
}
}
UPDATE
as per comment:
what if I have like 10 or 20 different components in my JPanel, is
there some way to reach them without having to make a lot of methods
Simply call getComponentCount on JPanel instance and than iterate using a for loop and getComponentAt(int i) this will allow you to get access to all components on JPanel:
CustomPanel cp=...;//this class extends jpanel
for(int i=0;i<cp.getComponentCount();i++) {
Component c=cp.getComponentAt(i);
if( c instanceof JButton) {
//do something
}
}
UPDATE 2
What if I have two or more objects that should be of the same class
but otherwise treated as separate objects, how can I tell them apart
using the loop that you've provided me
look at setName(String name) and getName of JButton this will allow you to assign the instance a unique name which can be gotten by getName(). Alternatively use setActionCommand(String name) and getActionCommand() to differentiate the buttons from another I prefer the latter.
Or you could even use their texts, via getText()

Can setDefaultCloseOperation work without specifying any object?

I came across a code which calls setdefaultcloseoperation() without reference to any object. I read that methods are called with reference to object. Here is the code
public class Mainpage extends JFrame implements ActionListener{
JFrame f = new JFrame("Mainpage");
public Mainpage() {
super("Mainpage");
f.setSize(1000,6000);
f.getContentPane().setLayout(null);
f.setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE); // how is this happening?
}
I want to know how setDefaultCloseOperation(EXIT_ON_CLOSE); is working. Thanks.
Well you extended JFrame. So in essence you are doing this.setDefaultOperation(EXIT_ON_CLOSE).
Also it doesn't make sense that you are creating a JFrame inside a JFrame.. unless this was an experiment of yours. Simple answer would be don't extend JFrame, and use
f.setDefaultOperation(EXIT_ON_CLOSE).
The method setDefaultCloseOperation refers to the current instance of JFrame.
Some side notes:
1) The second JFrame f is unnecessary here:
public class Mainpage extends JFrame implements ActionListener{
public Mainpage(){
super("Mainpage");
setSize(1000,6000);
...
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
2) Avoid using the null layout. See Doing Without a Layout Manager.

Categories