Je ne peux pas obtenir mon JFrame de la classe principale pour afficher JPanel d'une autre classe. Tout se compile sans erreurs.
JFrameTest.Java:
package jframetest;
import Java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JFrameTest extends JFrame {
public JFrameTest() {
FlowLayout mainLayout = new FlowLayout();
setSize(320, 480);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(mainLayout);
JPanel panelMain = new JPanel(mainLayout);
JButton testButton = new JButton("Test12");
panelMain.add(testButton);
JPanelOne panel = new JPanelOne();
panelMain.add(panel);
panel.setVisible(true);
add(panelMain);
}
public static void main(String[] arguments) {
JFrameTest frame = new JFrameTest();
frame.setVisible(true);
}
}
JPanelOne.Java:
package jframetest;
import Java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
public class JPanelOne extends JPanel {
public JPanelOne() {
FlowLayout layoutPanel = new FlowLayout();
JPanel panel = new JPanel(layoutPanel);
JButton button = new JButton("test");
panel.add(button);
panel.setVisible(true);
}
}
Est-ce une bonne pratique de garder différents JPanels dans leurs propres classes? (Exemple: vous voulez que JFrame contienne quelques JPanels de même taille, qui seront commutés en définissant setVisible () sur true/false)
MODIFIER
Merci pour toutes vos réponses. C'est noté. Revenons maintenant à ma question:
Maintenant que je sais comment ajouter des éléments GUI uniques créés dans d'autres classes, je veux savoir s'il est possible d'organiser des éléments avec le gestionnaire de disposition dans l'une des classes (peut-être dans un autre conteneur que JPanel), afin que je puisse les ajouter en tant que groupe organisé dans une mise en page (c'est pourquoi je demandais de créer JPanel entier dans une autre classe). Comme sur la photo:
Le code JPanel (cette 2e classe) pour cet exemple serait:
package jframetest;
import Java.awt.*;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import net.miginfocom.swing.MigLayout;
public class JPanelOne extends JPanel {
private JPanel panelSettingsMain;
private JLabel labelChooseLanguage, labelWordsCollection;
private JButton buttonSelectLanguage, buttonSelectCollection,
buttonStatistics, buttonPrintingOptions, buttonAddNewWordCollection,
buttonInterfaceCustomization;
private JSeparator separatorSettingsOne, separatorSettingsTwo,
separatorSettingsThree, separatorSettingsFour,
separatorSettingsFive;
private Color greenRegular, separatorGreenLight, separatorGreenDark;
public JPanelOne() {
// creating settings main panel
// setting up layout managers
MigLayout layoutSettingsMain = new MigLayout(
"insets 3 0 0 0");
// setting up colors
greenRegular = new Color(30, 165, 145);
separatorGreenLight = new Color(190, 240, 220);
separatorGreenDark = new Color(130, 205, 180);
panelSettingsMain = new JPanel(layoutSettingsMain);
panelSettingsMain.setBackground(Color.WHITE);
// setting up choose language label
labelChooseLanguage = new JLabel("Choose language:");
panelSettingsMain.add(labelChooseLanguage,
"gapleft 10, gaptop 15, width 200");
// setting up select language button
buttonSelectLanguage = new JButton("language");
buttonSelectLanguage.setForeground(greenRegular);
buttonSelectLanguage.setFocusPainted(false);
buttonSelectLanguage.setBorder(null);
buttonSelectLanguage.setContentAreaFilled(false);
buttonSelectLanguage.setCursor(new Java.awt.Cursor(
Java.awt.Cursor.HAND_CURSOR));
panelSettingsMain.add(buttonSelectLanguage, "gapbottom 15px, wrap");
// setting up light separator
separatorSettingsOne = new JSeparator();
separatorSettingsOne.setForeground(separatorGreenLight);
panelSettingsMain.add(separatorSettingsOne,
"span 2, width 320, gapbottom 15, wrap");
// setting up words collection label
labelWordsCollection = new JLabel("Words collection:");
panelSettingsMain.add(labelWordsCollection, "gapleft 10");
// setting up selectcollection button
buttonSelectCollection = new JButton("collection");
buttonSelectCollection.setForeground(greenRegular);
buttonSelectCollection.setFocusPainted(false);
buttonSelectCollection.setBorder(null);
buttonSelectCollection.setContentAreaFilled(false);
buttonSelectCollection.setCursor(new Java.awt.Cursor(
Java.awt.Cursor.HAND_CURSOR));
panelSettingsMain.add(buttonSelectCollection,
"gapbottom 15px, wrap");
// setting up dark separator
separatorSettingsTwo = new JSeparator();
separatorSettingsTwo.setForeground(separatorGreenDark);
panelSettingsMain.add(separatorSettingsTwo,
"span 2, width 320, gapbottom 15px, wrap");
// setting up show statistics button
buttonStatistics = new JButton("Show statistics");
buttonStatistics.setForeground(greenRegular);
buttonStatistics.setFocusPainted(false);
buttonStatistics.setBorder(null);
buttonStatistics.setContentAreaFilled(false);
buttonStatistics.setCursor(new Java.awt.Cursor(
Java.awt.Cursor.HAND_CURSOR));
panelSettingsMain.add(buttonStatistics,
"gapleft 10, gapbottom 15px, , wrap");
// setting up dark separator
separatorSettingsThree = new JSeparator();
separatorSettingsThree.setForeground(separatorGreenDark);
panelSettingsMain.add(separatorSettingsThree,
"span 2, width 320, gapbottom 15px, wrap");
// setting up printing options button
buttonPrintingOptions = new JButton("Printing options");
buttonPrintingOptions.setForeground(greenRegular);
buttonPrintingOptions.setFocusPainted(false);
buttonPrintingOptions.setBorder(null);
buttonPrintingOptions.setContentAreaFilled(false);
buttonPrintingOptions.setCursor(new Java.awt.Cursor(
Java.awt.Cursor.HAND_CURSOR));
panelSettingsMain.add(buttonPrintingOptions,
"gapleft 10, gapbottom 15px, wrap");
// setting up dark separator
separatorSettingsFour = new JSeparator();
separatorSettingsFour.setForeground(separatorGreenDark);
panelSettingsMain.add(separatorSettingsFour,
"span 2, width 320, gapbottom 15px, wrap");
// setting up add new Word collection button
buttonAddNewWordCollection = new JButton("Add new Word collection");
buttonAddNewWordCollection.setForeground(greenRegular);
buttonAddNewWordCollection.setFocusPainted(false);
buttonAddNewWordCollection.setBorder(null);
buttonAddNewWordCollection.setContentAreaFilled(false);
buttonAddNewWordCollection.setCursor(new Java.awt.Cursor(
Java.awt.Cursor.HAND_CURSOR));
panelSettingsMain.add(buttonAddNewWordCollection,
"gapleft 10, gapbottom 15px, , wrap");
// setting up dark separator
separatorSettingsFive = new JSeparator();
separatorSettingsFive.setForeground(separatorGreenDark);
panelSettingsMain.add(separatorSettingsFive,
"span 2, width 320, gapbottom 10px, wrap");
// setting up interface customization button
buttonInterfaceCustomization = new JButton(
"Interface customization");
buttonInterfaceCustomization.setForeground(greenRegular);
buttonInterfaceCustomization.setFocusPainted(false);
buttonInterfaceCustomization.setBorder(null);
buttonInterfaceCustomization.setContentAreaFilled(false);
buttonInterfaceCustomization.setCursor(new Java.awt.Cursor(
Java.awt.Cursor.HAND_CURSOR));
panelSettingsMain.add(buttonInterfaceCustomization,
"gapleft 10, gapbottom 15px, wrap");
}
}
Je pensais naviguer dans l'interface graphique du programme en définissant JPanels (comme dans l'exemple) sur visible ou non visible.
MODIFIER
Peut-être que je réfléchis trop, donc à la fin est-il acceptable d'avoir de grandes classes d'interface graphique et de contrôler la visibilité de différentes zones d'interface graphique en les définissant comme visibles ou non?
MODIFIER
J'ai regardé dans le didacticiel CardLayout chez Oracle et il semble que c'est bon pour ma tâche (en excluant la création de JPanels des classes externes, mais ça va). Je l'ai mal compris au début et je ne pensais à CardLayout qu'en termes de volet à onglets (que je ne voulais pas implémenter dans mon projet).
Avec un peu plus d'aide (utilisateur "Hilek" d'un autre site), j'ai réussi à obtenir le JPanel d'une autre classe à afficher dans la classe principale. Voici le code:
JFrameTest.Java:
import Java.awt.Color;
import Java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JFrameTest extends JFrame {
private JButton testButton;
private JPanel panelMain;
private JPanelOne panel;
public JFrameTest() {
// setting up JFrame
setLayout(null);
setPreferredSize(new Dimension(420, 90));
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// creating main JPanel (white)
panelMain = new JPanel();
panelMain.setBackground(Color.WHITE);
panelMain.setBounds(0, 0, 420, 90);
panelMain.setPreferredSize(new Dimension(200, 40));
add(panelMain);
// creating JButton in the main JPanel (white)
testButton = new JButton("Button from main class");
panelMain.add(testButton);
// creating new JPanelOne object from JPanelOne class containing black JPanel
panel = new JPanelOne();
// adding black JPanel to main JPanel (white)
panelMain.add(panel);
pack();
}
public static void main(String[] arguments) {
// creating JFrame object and setting it visible
JFrameTest frame = new JFrameTest();
frame.setVisible(true);
}
}
JPanelOne.Java:
import Java.awt.Color;
import Java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class JPanelOne extends JPanel
{
public JPanelOne()
{
// setting up black JPanel
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(220, 40));
panel.setBackground(Color.BLACK);
// creating button on external JPanel
JButton button = new JButton("Button (+JPanel) from external class");
// adding button to the black JPanel
panel.add(button);
// adding blackJPanel
add(panel);
}
}
Imprimer l'écran de l'exemple de travail:
http://i.stack.imgur.com/qKeBp.jpg
Peut-être que quelqu'un trouvera cela utile dans son problème.
Tout d'abord, pour répondre à votre question, vous devez ajouter une instance de votre panneau au cadre avec quelque chose comme ceci dans votre constructeur JFrameTest:
add(new JPanelOne());
Vous devez également ajouter votre bouton directement à JPanelOne lui-même:
public class JPanelOne extends JPanel {
public JPanelOne() {
JButton button = new JButton("test");
add(button);
}
}
Deuxièmement, je pense qu'il y a un problème avec ces lignes de code:
FlowLayout mainLayout = new FlowLayout();
// snip...
setLayout(mainLayout);
JPanel panelMain = new JPanel(mainLayout);
Chaque conteneur doit avoir sa propre instance d'un gestionnaire de disposition. Sinon, votre GUI fera des choses étranges:
setLayout(new FlowLayout());
JPanel panelMain = new JPanel(mainLayout);
N'appelez pas setSize()
sur votre JFrame. Au lieu de cela, laissez les mises en page définir les tailles appropriées de leurs composants et de l'interface graphique. Après avoir ajouté tous les composants à votre GUI, appelez pack()
sur le JFrame, puis appelez setVisble(true)
. Notez que la plupart des mises en page respectent davantage la taille préférée d'un composant que sa taille.
En outre, votre appel setVisible(true)
sur vos composants individuels est inutile (à moins que vous ne changiez leur visibilité après que l'interface graphique soit opérationnelle pour une raison quelconque). Vous voudrez également en savoir plus sur l'utilisation des gestionnaires de mise en page et vous utiliserez probablement moins FlowLayout une fois que vous les aurez étudiés.
Modifier
Concernant votre dernière modification:
Peut-être que je réfléchis trop, donc à la fin est-il acceptable d'avoir de grandes classes d'interface graphique et de contrôler la visibilité de différentes zones d'interface graphique en les définissant comme visibles ou non?
Je répondrai que parfois cela est utile, par exemple si vous voulez changer une calculatrice standard en calculatrice scientifique, parfois il est bon d'afficher simplement un JPanel déjà créé rempli des boutons de calcul avancé en utilisant setVisible (true). Si d'un autre côté vous voulez permuter les "vues" de votre GUI pour refléter un changement substantiel dans son état, par exemple un traitement de texte passant du mode d'édition au mode d'impression, vous pouvez échanger facilement JPanels pour le faire en utilisant un CardLayout.
Le problème vient de la classe JPanelOne
. Il hérite de JPanel
mais dans le constructeur, vous créez un nouveau JPanel
puis vous y ajoutez un bouton. Si vous faites cela à la place:
public class JPanelOne extends JPanel {
public JPanelOne() {
JButton button = new JButton("test");
add(button);
}
}
cela devrait fonctionner comme vous l'attendez.