Error in following code is: java.lang.IllegalArgumentException: adding container's parent to itself.
This is the code:
public class humev extends JFrame implements ActionListener{
//Dichiarazione variabili e costanti
private static final int larghezza = 1300;
private static final int altezza = 1000;
private static final String nome = "Human Evolution";
private JLabel lab;
private JButton gioca;
private JPanel pang;
public humev(){
try{
pang = new JPanel();
gioca = new JButton("Gioca!");
gioca.addActionListener(this);
lab = new JLabel();
gioca.add(gioca);
lab.add(lab);
pang.setLayout(null);
}
catch(Exception e1){
System.err.println(e1);
System.err.println("Impossibile caricare il frame di gioco!");
}
}
public static void main(String[] args) {
//Finestra
try{
humev h = new humev();
JFrame finestra = new JFrame(nome);
Dimension dim_finestra = new Dimension(larghezza, altezza);
finestra.setPreferredSize(dim_finestra);
finestra.setMaximumSize(dim_finestra);
finestra.setResizable(false);
finestra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
finestra.pack();
finestra.setVisible(true);
}
catch(Exception e2){
System.err.println(e2);
System.err.println("Impossibile caricare la finestra. Frame non caricato");
}
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == gioca){
lab.setText("Gioco avviato con successo!");
}
}
}
You cannot add a labelinto a label :-
lab.add(lab);
Aldo you cannot add a button on a button :-
gioca.add(gioca);
Try adding them to the JPanel or ContentPane instead like
:-
pang.add(gioca);
pang.add(lab);
getContentPane().add(pang);
EDIT:-
For Showing the JFrame you need to do first add your JPanel to JFrame then set the visibility of JFrame to true something like :-
finestra.add(pang); // add panel to frame
finestra.setVisible(true); // show frame visibility to true
Also don't set the layout to null :-
pang.setLayout(null);
Else you will need to set the bounds yourself. So just comment this line.
try to run this example.there is bunch of problems in your code.
you are adding component to itself
gioca.add(gioca); // don't do this
use layouts .don't use null
pang.setLayout(null); // don't do this .use layouts .and even if you use null then
//use bounds to absolutely position .if you use null layout and if you add using `.add()`
//then you will not see those components .
complete code
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class humev extends JFrame implements ActionListener {
private static final int larghezza = 1300;
private static final int altezza = 1000;
private static final String nome = "Human Evolution";
private final JLabel lab;
private final JButton gioca;
private final JPanel pang;
public humev() {
super(nome);
pang = new JPanel();
//pang.setLayout(new FlowLayout()); // use appropriate layout .for example flowlayout.since flowlayout is default layout for jpanel you can avoid it.but don't use null
gioca = new JButton("Gioca!");
gioca.addActionListener(this);
lab = new JLabel("lable");
pang.add(gioca);
pang.add(lab);
add(pang); // add pang panel to frame
Dimension dim_finestra = new Dimension(larghezza, altezza);
setPreferredSize(dim_finestra);
setMaximumSize(dim_finestra);
//setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
pack();
}
public static void main(String[] args) {
humev humev = new humev();
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == gioca) {
lab.setText("Gioco avviato con successo!");
}
}
}
IllegalArgumentException is an Unchecked Exception.
It rises explicitly by API Developer or Programmer to indicate that a method has invoked with illegal argument.
example:
Thread t = new Thread();
t.setPriority(15);
output:
RuntimeException: IllegalArgumentExcepion
The valid range of Thread priority is 1 to 10, if we are trying to set the priority with any other value, then we will get IllegalArgumentException.
Related
I want to print multiple label according to the number(no string allowed) you wrote in a text field first. I want it to be dynamical. I want it to change every time you type something in the text field.
So far it can read if it's a number or a string and throw exception if the text doesn't match the requirement.
I've try multiple thing to print multiple Jlabel on the screen, but it didn't work so far.
Here's the code: can you help me?
The main window class
public class MainWindow extends JFrame {
private MainPanel mp = new MainPanel();
public MainWindow()
{
this.setVisible(true);
this.setTitle("Calculateur sur 100");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(200, 400);
this.setLocationRelativeTo(null);
this.setContentPane(mp);
}}
The mainPanel class
public class MainPanel extends JPanel implements ActionListener, MouseListener, KeyListener {
private JTextField tI = new JTextField("Pourcentage");
private JOptionPane jop3 = new JOptionPane();
public MainPanel()
{
this.add(tI);
tI.addKeyListener(this);
tI.addMouseListener(this);
}
//Mathematic calculation
private double onHundred(int tot, int now)
{
return (tot / 100) * now;
}
public void keyReleased(KeyEvent e)
{
boolean ok = true;
try
{
int numbs = Integer.parseInt(tI.getText());
}
catch(Exception s)
{
tI.setText("");
jop3.showMessageDialog(null, "Veuillez entrer seulement des chiffres", "Erreur", JOptionPane.ERROR_MESSAGE);
ok = false;
}
if(ok)
{
System.out.print("Supposed to print");
JLabel[] label = new JLabel[Integer.parseInt(tI.getText())];
for(int i = Integer.parseInt(tI.getText()); i <= 0; i--)
{
label[i] = new JLabel(i + " = " + Math.ceil(onHundred(Integer.parseInt(tI.getText()), i)));
label[i].setVisible(true);
this.add(label[i]);
}
}
}
You MainWindow class should look something like this:
public class MainWindow extends JFrame {
private MainPanel mp = new MainPanel();
public static void main(String[] args) {
new MainWindow();
}
public MainWindow() {
setContentPane(mp);
setTitle("Calculateur sur 100");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
}
Note the order: setContentPane then pack then setVisible. pack replaces setSize as it determines the preferred size of the window based on its components.
I modified your MainPanel class:
public class MainPanel extends JPanel {
private JTextField tI = new JTextField("Pourcentage");
JPanel labelPanel = new JPanel();
public MainPanel() {
setLayout(new BorderLayout());
tI.getDocument().addDocumentListener(new MyDocumentListener());
add(tI, BorderLayout.PAGE_START);
add(labelPanel);
}
private int check() {
int numL;
try {
numL = Integer.parseInt(tI.getText());
} catch (NumberFormatException exc) {
return 0;
}
return numL > 100? 100 : numL;
}
private void update(int numL) {
labelPanel.removeAll();
for (int i = 0; i < numL; i++)
labelPanel.add(new JLabel(String.valueOf(i+1)));
JFrame mainWindow = ((JFrame) SwingUtilities.getWindowAncestor(this));
mainWindow.pack();
mainWindow.repaint();
}
class MyDocumentListener implements DocumentListener {
#Override
public void insertUpdate(DocumentEvent e) {
update(check());
}
#Override
public void removeUpdate(DocumentEvent e) {
update(check());
}
#Override
public void changedUpdate(DocumentEvent e) {
}
}
}
Explanation:
The main panel has the text field separately from another panel which updates dynamically to contain the labels.
The text field uses a DocumentListener instead of a KeyListener to listen to changes in its contents. This is the correct approach for many reasons I will not get into here unless really necessary.
Whenever the text changes, a check method verifies that the input is a number. If it's not it returns 0. If it's more than 100 it returns 100. You can change this behavior as you need.
The value from check is passed to update which clears all the previous labels and reconstructs them. (You can do a bit of optimization here if you want by keeping labels in memory but not displaying them. If the cap is 100 as in my example this won't be noticeable.). The main frame then recalculates the space it needs for all the labels and then repaints.
The labels appear next to each other because the default layout for JPanel is FlowLayout. You can change this as needed.
First - you have Integer.parseInt(tI.getText()) a number of times within the same keyReleased function. When you have done the first check to assign it to int numbs, then use numbs from then on, instead of referring back to tI.getText(). Theoretically the user input can change while you are processing your array, which will cause runtime exceptions or undesired results. Hint - declare numbs directly under ok.
Second - after you add controls programmatically, you need to invalidate the control on to which you are adding them, ie your MainPanel. The invalidate directive tells the control that it is not drawn correctly and needs to be repainted (do this at the completion of your loop). Look through the documentation for JPanel for invalidate and paint.
Hi i have a class where i am using mouseclick event i want to call another class when i click from my mouse
MouseListener mouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent mouseEvent) {
JList theList = (JList) mouseEvent.getSource();
if (mouseEvent.getClickCount() == 2) {
int index = theList.locationToIndex(mouseEvent.getPoint());
if (index >= 0) {
Object o = theList.getModel().getElementAt(index);
// System.out.println("Double-clicked on: " + o.toString());
String a=o.toString();
LiistSelection.setListIndex(a);
System.out.println(LiistSelection.getListIndex());
new MyGui4();
}
}
}
};
i want to call this class when user click on list then new window should open
here is my class mygui4.java
public class MyGui4 extends JFrame
{
JLabel jLabel1;
Container pane;
private static ResultSet resultSet = null;
public void Gui( )
{
{
getContentPane().setBackground(new java.awt.Color(255,153,51));
}
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Container c = getContentPane();
setUndecorated(true);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setBounds(0,0,screenSize.width, screenSize.height);
ImageIcon image = new ImageIcon("E:\\SOFTWARE\\TrainPIS\\res\\drawable\\a0.png");
Border border = LineBorder.createGrayLineBorder();
jLabel1 = new JLabel(image);
jLabel1.setBorder(border);
jLabel1.setBackground(Color.red);
c.add(jLabel1);
setLayout(null);
}
public static void main( String[] args )
{
final MyGui4 frame = new MyGui4();
frame.Gui();
frame.setVisible(true);
}
}
You want to Create a object of another Class and call a function using a object.
class second
{
//.....
public void function()
{
//........
}
public void function(int index)
{
//..........
}
}
second s=new second();
s.function()//calling function
int i=10;
s.function(i)//calling function with parameter
Try This Example :
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class m extends JFrame
{
String s="The Value of List is 10";
m()
{
setVisible(true);
pack();
setLayout(null);
JButton b=new JButton("Click to Open another form");
b.setBounds(10,10,200,40);
add(b);
b.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
new s(s);//calling another class contructor
}
});
}
public static void main (String[] args)
{
new m();
}
}
class s extends JFrame
{
s(String s)
{
setVisible(true);
setSize(100,100);
setTitle(s);
}
}
Click The button Another Class and Open The Window
It looks to me like you are tying to invoke the class MyGui4 from the command line when you start the JVM or from another application when you click on the JList, If so then the code needs to be the same in both places.
When invoked from the command line the main() method is invoked which in turn invokes 3 lines of code:
final MyGui4 frame = new MyGui4();
frame.Gui();
frame.setVisible(true);
When you invoke the code when clicking on the JList you invoke 1 line of code:
new MyGui4();
Can you tell me what the difference is?
Of course I still don't understand the point of this code because none of the methods in your MyGui4 class accept a parameter. So it doesn't matter which item in the JList you click on you will still display the same GUI with the same information. You need to pass the selected object from your JList to your GUI.
im struggling again, with doing a program in java that converts the temperature from celsius to fahrenhiet, but it must be done in a GUI so that the user may enter in a number for celsius and click a botton to convert it. ive been modeling it off of a example in my book however in the book it shows it working with out having a static main(), but my IDE gave me an error saying that it was needed, so ive added a static main() and ive tried calling the tempwindow() to see if that would work but still nothing and even if i comment out the call it doesnt give me a error but nothing happens.
im hopping someone can help show me what im doing wrong and how i should go about this.
import javax.swing.JOptionPane;
import javax.swing.*;
import java.awt.event.*;
public class tempcon extends JFrame
{
private JPanel panel;
private JLabel messageLabel;
private JTextField tempC;
// private JRadioButton tempF;
// private ButtonGroup radioButtonGroup;
private JButton calcButton;
private final int WINDOW_WIDTH = 400;
private final int WINDOW_HEIGHT = 100;
public tempwindow()
{
setTitle("Temurture convertion");
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buildPanel();
add(panel);
setVisible(true);
}
private void buildPanel()
{
messageLabel = new JLabel("enter tempurture in celsius");
tempC = new JTextField(10);
calcButton = new JButton("convert");
calcButton.addActionListener(new CalcButtonListener());
panel = new JPanel();
panel.add(messageLabel);
panel.add(tempC);
panel.add(calcButton);
}
private class CalcButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String input;
double temp;
input = tempC.getText();
temp = Double.parseDouble(input) * 1.8 + 32;
JOptionPane.showMessageDialog(null, "that is " + temp + "degrees fehrenhiet");
}
}
public static void main(String[] args)
{
tempwindow();
}
}
You are doing a few things wrong:
Your constructor can't have a different name from your class name
You need to instantiate the object to call the constructor, rather instantiating an object does call the constructor but you can't just access it like a method.
You should use the Java naming conventions for class names.
The class:
public class TempCon extends JFrame
{
// Variable declarations
public TempCon() // Constructor should match the Class name
{
}
}
The main class:
public static void main(String[] args)
{
TempCon converter = new TempCon();
}
public static void main(String[] args)
{
tempcon myTempWindowInstance = new tempcon();
myTempWindowInstance.tempwindow();
}
You never initialize a tempcon. Your constructor must have the same name as the class, so I recommend the following changes instead:
Replace public tempwindow() with public tempcon() to correct the constructor.
public tempcon()
{
setTitle("Temurture convertion");
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buildPanel();
add(panel);
setVisible(true);
}
create an instance of tempcon using new, which calls the constructor:
public static void main(String[] args)
{
tempcon myTempWindowInstance = new tempcon();
}
please write return type your function like.
public void tempwindow()
create object of class and call method.
public static void main(String[] args)
{
tempcon t=new tempcon();
t.tempwindow();
}
and learn java object java object oriented programming.
I have two Action Listener inner-classes inside one main class. Each one corresponds to its own button. One of the Action Listeners is coded to generate an Array List. The other simply writes that Array List to a Text Field.
My question is how can I refer to/access that data from the other Action Listener? The code below compiles but when I check the contents of the Array List from the second Action Listener, it is empty ([]).
I'm guessing this has something to do with the Array List re-instantiating when the other Action Listener's actionPerformed method is called. How can I work around this? (The code here is just the 2 Action Listeners).
// Create a Button Listener Inner Class for Input Route Button.
class InputRouteButtonHandler implements ActionListener {
List<String> routeStopList = new ArrayList<String>();
public void actionPerformed(ActionEvent event) {
String city1 = (String) cityCombo1.getSelectedItem();
String city2 = (String) cityCombo2.getSelectedItem();
if (city1.equals(city2)) {
JOptionPane.showMessageDialog(null, "Invalid route chosen. Please choose two different cities.");
} else {
routeStopList.add(city1); //Add city1 to start of array.
int dialogResult;
do {
String routeStop = JOptionPane.showInputDialog("Enter a stop between the 2 cities:");
routeStopList.add(routeStop);
dialogResult = JOptionPane.showConfirmDialog(null, "Add another stop?");
} while (dialogResult.equals(JOptionPane.YES_OPTION));
routeStopList.add(city2); //Add city2 to end of array.
System.out.println(routeStopList); //Just checking ArrayList contents
}
}
}
// Create a Button Listener Inner Class for Route Button.
class RouteButtonHandler extends InputRouteButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent event) {
String city1 = (String) cityCombo1.getSelectedItem();
String city2 = (String) cityCombo2.getSelectedItem();
System.out.println(routeStopList); //Just checking ArrayList contents
if (city1.equals(city2)) {
JOptionPane.showMessageDialog(null, "Invalid route chosen. Please choose two different cities.");
} else {
for (int i = 0; i < routeStopList.size(); i++) {
String addedRoute = routeStopList.get(i);
adminPanelTextArea.append(addedRoute + "\n");
}
}
}
}
You are right, your problem is due to your creating two ArrayLists, lists that have absolulely no relationship with each other, other than holding the same type of objects and having the same names. A solution is to create one Model class that is shared by both ActionListener classes, and in this model class, have your ArrayList. Then give your ArrayList classes a setModel(Model model) method or constructor, and pass in a reference to the single Model object into both ActionListeners.
One other consideration is to use a single Control class to handle your listener type code, and then have your Control class hold a Model field.
As an aside, this is dangerous code:
if (city1 == city2) {
Don't compare Strings using ==. Use the equals(...) or the equalsIgnoreCase(...) method instead. Understand that == checks if the two objects are the same which is not what you're interested in. The methods on the other hand check if the two Strings have the same characters in the same order, and that's what matters here.
For example, say you have two buttons that want to manipulate a JList, one wanting to add text, the other wanting to clear it, then you could pass the JList's model into both button handlers. An example program could look like:
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class ShareList extends JPanel {
private static final String PROTOTYPE_CELL_VALUE = "ABCDEFGHIJKLMNOP";
private static final int VISIBLE_ROW_COUNT = 10;
private JTextField textField = new JTextField(10);
private DefaultListModel<String> listModel = new DefaultListModel<>();
private JList<String> myList = new JList<>(listModel);
public ShareList() {
myList.setPrototypeCellValue(PROTOTYPE_CELL_VALUE);
myList.setVisibleRowCount(VISIBLE_ROW_COUNT);
myList.setFocusable(false);
JPanel buttonPanel = new JPanel();
AddHandler addHandler = new AddHandler(listModel, this);
textField.addActionListener(addHandler);
buttonPanel.add(new JButton(addHandler));
buttonPanel.add(new JButton(new ClearHandler(listModel)));
JPanel rightPanel = new JPanel(new BorderLayout());
rightPanel.add(textField, BorderLayout.NORTH);
rightPanel.add(buttonPanel, BorderLayout.CENTER);
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
add(new JScrollPane(myList));
add(rightPanel);
}
public String getText() {
textField.selectAll();
return textField.getText();
}
private static void createAndShowGui() {
JFrame frame = new JFrame("ShareList");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ShareList());
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 AddHandler extends AbstractAction {
private DefaultListModel<String> listModel;
private ShareList shareList;
public AddHandler(DefaultListModel<String> listModel, ShareList shareList) {
super("Add");
putValue(MNEMONIC_KEY, KeyEvent.VK_A);
this.listModel = listModel;
this.shareList = shareList;
}
public void actionPerformed(ActionEvent e) {
String text = shareList.getText();
listModel.addElement(text);
};
}
#SuppressWarnings("serial")
class ClearHandler extends AbstractAction {
private DefaultListModel<String> listModel;
public ClearHandler(DefaultListModel<String> listModel) {
super("Clear");
putValue(MNEMONIC_KEY, KeyEvent.VK_C);
this.listModel = listModel;
}
public void actionPerformed(ActionEvent e) {
listModel.clear();
};
}
I have 2 classes.
when I put bold 3 lines in the method addCourses() the dialog does not show combobox in the Panel
but when I remove from addCourses and put those bold lines in the constructor, JComboBox are shown in the Panel.
But data will not show because data items updates to ComboBox will happen after Constructor is created.
How can I solve this problem.
this.mainPanel.add(courseCombo, BorderLayout.NORTH);
this.mainPanel.add(sessionCombo, BorderLayout.CENTER);
this.mainPanel.add(courseButton, BorderLayout.SOUTH);
public class Updator {
CourseListFrame clf = new CourseListFrame();
for(...){
clf.addContentsToBox(displayName, className);
}
clf.addCourses();
}
and second class is
public class CourseListFrame extends JDialog implements ActionListener {
public JPanel mainPanel = new JPanel(new BorderLayout(2, 2));
public JButton courseButton = new JButton(("Submit"));
public JComboBox courseCombo;
public JComboBox sessionCombo;
public Multimap<String, String> map; // = HashMultimap.create();
public static CourseListFrame courseListDialog;
public CourseListFrame() {
super(this.getMainFrame());
this.getContentPane().add(mainPanel);
map = HashMultimap.create();
courseCombo = new JComboBox();
courseCombo.addItem("Select Courses");
courseCombo.addActionListener(this);
sessionCombo = new JComboBox();
}
public void addContentsToBox(String course, String session) {
map.put(course, session);
courseCombo.addItem(course);
}
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox) e.getSource();
String str = (String) cb.getSelectedItem();
setSessionCombo(str);
}
public void setSessionCombo(String course) {
if (map.containsKey(course)) {
sessionCombo.removeAllItems();
Iterator it = map.get(course).iterator();
while (it.hasNext()) {
sessionCombo.addItem(it.next());
}
}
}
public void addCourses() {
this.mainPanel.add(courseCombo, BorderLayout.NORTH);
this.mainPanel.add(sessionCombo, BorderLayout.CENTER);
this.mainPanel.add(courseButton, BorderLayout.SOUTH);
}
public static void showCourseListDialog() {
if (courseListDialog == null) {
courseListDialog = new CourseListFrame();
}
courseListDialog.pack();
courseListDialog.setVisible(true);
courseListDialog.setSize(260, 180);
}
}
The reason why they arent showing is because you are probably calling the static showCourseListDialog() to show your dialog. This method will test whether your static courseListDialog is null, and if so, create one and set that dialog visible, not the clf that you instantiated.
If in your showCourseListDialog() you call the addCourses() method after instantiating your 'singleton', you should be OK:
public static void showCourseListDialog() {
if (courseListDialog == null) {
courseListDialog = new CourseListFrame();
courseListDialog.addCourses();// <<---- this is key!
}
courseListDialog.pack();
courseListDialog.setVisible(true);
courseListDialog.setSize(260, 180);
}
That said, by having the static courseListDialog, it is apparent that you want that dialog to be a singleton. If that is the case, I would at least make your constructor private. You want to proactively avoid the situation that you are getting into where you can construct multiple instances of a singleton. You still would have a race condition to deal with in your showCourseListDialog, but as you will only be calling this method in the EDT, you should be safe.
Take a look at this and other topics on Singleton development in Java (and dont forget to read the con arguments where it is described as an anti-pattern)