JTabbedPane problème focus

Résolu/Fermé
Hitsaki - 26 juin 2017 à 01:03
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 - 26 juin 2017 à 16:46
Bonjour à tous,

étant étudiant en licence informatique, j'ai décidé de crée un paint pour m'entrainer, j'ai donc respecter le schéma suivant :
- Une class Fenetre (extends JFrame) , elle contient un menu (via lequel on peut crée des nouveaux panneaux ainsi que l'Objet JTabbedPane (onglets)
- A chaque fois qu'on appuie sur "nouveau" pour un nouveau panneau, un onglet est crée , cet onglet contient une instance de Panneau (extends JPannel), qui lui meme contient des boutons pour le choix de la couleur de dessins, quelques outils, ainsi qu'une zone de dessin ( Class Draw, extends JPannel, implements mouse listener).
Donc on crée une fenetre, puis quand on crée un nouveau projet, cela crée un panneau qui lui meme contient des boutons et un Draw.
Tout marche niquel sur le paint, mais :

Mon problème est le suivant, quand je lance le programme : Je crée un onglet , je peux dessiner dessus. Je recrée un onglet, la le focus passe sur le DERNIER onglet crée, MEME SI je reviens sur le premier onglet (et j'ai bien vérifier qu'il comprend bien que j'y suis) il dessine sur le Draw du DERNIER ONGLET OUVERT et cela peut importe le nombre d'onglets ouvert, j'ai donc essayer de stocké tout les panneau (onglets) dans un tableau pour ensuite donner le focus a celui sur lequel je vais me rendre (avec tabpan[onglets.getSelectedIndex()].requestFocusInWindow(); ) (j'ai aussi essayer de donner le focus a la Draw avec tabpan[onglets.getSelectedIndex()].getDraw().requestFocusInWindow();

mais sans succès. Je ne comprend pas pourquoi quoi que je fasse, meme quand je suis sur un autre onglet les points de touts les onglets s'affiche bien (si je dessine un A sur le premier, puis un B sur le deuxieme quand je switch entre les deux il m'affiche bien un coup A un coup B) mais une fois que j'ai deux onglets ou plus il dessine uniquement sur le dernier. je met ici le code de la classe Fenetre, faites moi signe si vous voulez les autres classes. Merci par avance

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Fenetre extends JFrame {

private Panneau [] tabpan = new Panneau [2000];
JTabbedPane onglets;
//private Panneau pan; // panneau principal de l'appli
private static int compt = 0;

public Fenetre () {
this.setTitle("Paint"); // titre fenetre
this.setSize(900,700); // taille fenetre
this.setMinimumSize(new Dimension (900,700)); // taille minimum possible de la fenêtre
//this.setLocationRelativeTo(null); // positionement fenetre au centre
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // quitte processus quand on ferme fenetre
//pan = new Panneau(); // crée le panneau principal de la fenetre ou on mettera les composants
onglets = new JTabbedPane();
onglets.addChangeListener(new Change());
//JButton close = new JButton ("x");
//close.addActionListener(new Close());
//onglets.addTab("Image " + compt, null, pan,null);
JMenuBar barre = new JMenuBar ();
JMenu fichier = new JMenu ("Fichier");
JMenuItem nouveau = new JMenuItem ("Nouveau");
nouveau.addActionListener(new ActionPan());
fichier.add(nouveau);
barre.add(fichier);
this.setJMenuBar(barre);
setContentPane(onglets);
//this.setContentPane(onglets); // inclus le panneau crée dans la fenetre
this.setVisible(true); // rend la fenêtre visible
//pan.repaint(); // appel la methode paintComponent() héritée de JPanel
}

public static void main(String[] args) {
Fenetre paint = new Fenetre (); // crée la fenetre principale
}

class ActionPan implements ActionListener {
public void actionPerformed(ActionEvent arg0) {
tabpan[compt] = new Panneau();
onglets.addTab("Image " + (compt+1), null, tabpan[compt],null);
compt++;
}
}

class Change implements ChangeListener {
public void stateChanged(ChangeEvent event){
tabpan[onglets.getSelectedIndex()].requestFocusInWindow();
//tabpan[onglets.getSelectedIndex()].getDraw().requestFocusInWindow();
}
}

// window adapter pour fermer la fenêtre quand on clique sur la croix rouge
class Fermer extends WindowAdapter {
public void windowClosing (WindowEvent evt) {
evt.getWindow().dispose();
System.exit(0);
}
}
}
A voir également:

1 réponse

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
26 juin 2017 à 10:06
Bonjour,

On n'a pas la classe Panneau pour pouvoir reproduire ton problème.
Est-ce que tu pourrais nous fournir un code complet pour tester ?

PS. Panneau[2000] c'est violent, tu penses vraiment utiliser 2000 onglets en même temps ? Ici il te faudrait plutôt une liste qu'un tableau, ça te permettra d'avoir autant d'onglets que tu veux même si tu ne sais pas combien tu peux en avoir au maximum.
0
Hitsa Messages postés 2 Date d'inscription lundi 26 juin 2017 Statut Membre Dernière intervention 26 juin 2017
26 juin 2017 à 14:24
Salut merci de ta réponse, je comptais effectivement utiliser ArrayList<Panneau> la c'était juste pour le test, je te laisse les autre classes :

import java.awt.*;
import java.awt.event.*; // action listener
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;

public class Panneau extends JPanel{

private static Draw draw;
private JComboBox curseur;
private MyButton gomme;
private MyButton crayon;

// ce constructeur crée et organise le Panneau principal dans lequel on place tout les éléments
public Panneau () {
setBackground(Color.lightGray);
setLayout(new GridBagLayout());
// paramètres du composant Draw (zone de dessin)
draw = new Draw (); // declaration panel
draw.addMouseListener(new Mouse());
draw.addMouseMotionListener(new Mouse());
draw.setPreferredSize(new Dimension(700, 500)); // taille préférée
draw.setBackground(Color.white); // couleur
GridBagConstraints gbc = new GridBagConstraints(); // créations des contraintes
gbc.gridx = gbc.gridy = 0; // placement dans la grille
gbc.gridwidth = 1;
gbc.gridheight = 2;
gbc.fill = GridBagConstraints.BOTH; // redimensionnement quand fenetre s'aggrandit
gbc.weightx = gbc.weighty = 1.0;
gbc.insets = new Insets(20, 20, 10, 20); // marges autour
gbc.gridwidth = GridBagConstraints.RELATIVE; // avant dernier de sa ligne
gbc.gridheight = 2;
add(draw,gbc); // ajout de la barre de couleurs

// paramètres du composant couleur
Panel couleurs = new Panel ();
couleurs.setPreferredSize(new Dimension(80, 250));
couleurs.setBackground(Color.lightGray);
GridBagConstraints gbc2 = new GridBagConstraints();
gbc2.gridx = 1;
gbc2.gridy = 1;
gbc2.insets = new Insets(0, 0, 20, 20); // marges
gbc2.gridheight = 1;
gbc2.gridwidth = GridBagConstraints.REMAINDER; // dernier de sa ligne
add(couleurs, gbc2);

// on ajoute la zone de séléction des outils
Panel outils = new Panel ();
outils.setPreferredSize(new Dimension(80, 300));
outils.setBackground(Color.gray);
GridBagConstraints gbc3 = new GridBagConstraints();
gbc3.gridx = 1;
gbc3.gridy = 0;
gbc3.insets = new Insets(20,0,10,20); // marges autours
gbc3.fill = GridBagConstraints.VERTICAL; // s'étend verticalement si fenetre grandit
gbc3.gridwidth = GridBagConstraints.REMAINDER; // dernier de sa ligne
gbc3.gridheight = 1;
add(outils, gbc3);

// ajout de la selection de curseur dans les outils
JLabel labComb = new JLabel("Curseur :");
labComb.setForeground(Color.black); // couleur du texte
outils.setLayout(new FlowLayout());
outils.add(labComb);
curseur = new JComboBox();
curseur.addActionListener(new ActionComb());
curseur.addItem("Rond");
curseur.addItem("Carré");
outils.add(curseur);

// on ajoute la zone de selection de taille
JSlider taille = new JSlider(); // slider pour séléctionner la taille
taille.setPreferredSize(new Dimension(65, 10));
taille.setMinimum(1); // min de selection
taille.setMaximum(400); // max de selection
taille.setValue(30); // valeur par défaut
JLabel labtaille = new JLabel ("Cuseur taille : " + taille.getValue() + " px"); // label accompagnant la séléction
labtaille.setForeground(Color.black);
taille.addChangeListener(new ChangeListener(){ // ajout du listener pour afficher la taille en live
public void stateChanged(ChangeEvent event){
labtaille.setText("Curseur taille : " + taille.getValue() + "px");
draw.setCurseurWidth(taille.getValue());
}
});
GridBagConstraints gbc4 = new GridBagConstraints(); // contraintes slider
gbc4.gridx = 0;
gbc4.gridy = 2;
gbc4.gridwidth = GridBagConstraints.REMAINDER; // dernier de sa ligne
gbc4.gridheight = 1;
gbc4.anchor = GridBagConstraints.LINE_START; // il reste a gauche
gbc4.insets = new Insets(0, 20, 2, 0); // marge
outils.add(taille, gbc4); // ajout au panel

// on ajoute le label "outils" dans outils
JLabel laboutils = new JLabel ("Outils :");
laboutils.setForeground(Color.black);
outils.add(laboutils);

// on ajoute la gomme
gomme = new MyButton ("boutons/gomme.png", "boutons/gommeap.png");
gomme.addActionListener(new Action());
gomme.setPreferredSize(new Dimension(30,30));
outils.add(gomme);

// on ajoute le crayon
crayon = new MyButton ("boutons/crayon.png", "boutons/crayonap.png");
crayon.addActionListener(new Action());
crayon.setPreferredSize(new Dimension(30,30));
outils.add(crayon);

// label avec la taille
GridBagConstraints gbc5 = new GridBagConstraints(); // contraintes du label
gbc5.gridx = 0;
gbc5.gridy = 3;
gbc5.gridwidth = GridBagConstraints.REMAINDER; // dernier de sa ligne
gbc5.gridheight = GridBagConstraints.REMAINDER; // dernier de sa colonne
gbc5.anchor = GridBagConstraints.LINE_START; // il reste a gauche
gbc5.insets = new Insets(0, 20, 20, 0); // marge
add(labtaille, gbc5); // ajout au panel

// on crée et ajoute les couleurs dans la zone de couleurs
couleurs.setLayout(new GridLayout(6,2));
JButton black = new JButton ("black");
black.addActionListener(new Action ());
black.setForeground(Color.white);
black.setBackground(Color.black);
couleurs.add(black);
JButton gray = new JButton("gray");
gray.addActionListener(new Action ());
gray.setBackground(Color.gray);
couleurs.add(gray);
JButton orange = new JButton("orange");
orange.addActionListener(new Action ());
orange.setBackground(Color.orange);
couleurs.add(orange);
JButton yellow = new JButton("yellow");
yellow.addActionListener(new Action ());
yellow.setBackground(Color.yellow);
couleurs.add(yellow);
JButton blue = new JButton("blue");
blue.addActionListener(new Action ());
blue.setBackground(Color.blue);
couleurs.add(blue);
JButton green = new JButton("green");
green.addActionListener(new Action ());
green.setBackground(Color.green);
couleurs.add(green);
JButton pink = new JButton("pink");
pink.addActionListener(new Action ());
pink.setBackground(Color.pink);
couleurs.add(pink);
JButton cyan = new JButton("cyan");
cyan.addActionListener(new Action ());
cyan.setBackground(Color.cyan);
couleurs.add(cyan);
JButton lightGray = new JButton("lightGray");
lightGray.addActionListener(new Action ());
lightGray.setBackground(Color.lightGray);
couleurs.add(lightGray);
JButton red = new JButton("red");
red.addActionListener(new Action ());
red.setBackground(Color.red);
couleurs.add(red);
JButton darkGray = new JButton("darkGray");
darkGray.addActionListener(new Action ());
darkGray.setBackground(Color.darkGray);
couleurs.add(darkGray);
JButton magenta = new JButton("magenta");
magenta.addActionListener(new Action ());
magenta.setBackground(Color.magenta);
couleurs.add(magenta);
}

public Draw getDraw () {
return draw;
}

class MyButton extends JButton {
private static final long serialVersionUID = 1L;
public MyButton(String icon, String iconHover) {
super("");
setContentAreaFilled(false); // On met à false pour empêcher le composant de peindre l'intérieur du JButton.
setBorderPainted(false); // De même, on ne veut pas afficher les bordures.
setFocusPainted(false); // On n'affiche pas l'effet de focus.
setIcon(new ImageIcon(icon));
setRolloverIcon(new ImageIcon(iconHover));
}
}


// ------------------------------ LISTENERS DES DIFFERENTS ELEMENTS --------------------------------------------

// gère les boutons de couleurs
class Action implements ActionListener {
public void actionPerformed (ActionEvent evt) {
String etiquette = evt.getActionCommand(); // recupère l'étiquette du bouton appuyé
// la compare une a une au boutons couleurs :
if (etiquette.equals("black"))
draw.setCol(Color.black);
else if (etiquette.equals("gray"))
draw.setCol(Color.gray);
else if (etiquette.equals("orange"))
draw.setCol(Color.orange);
else if (etiquette.equals("yellow"))
draw.setCol(Color.yellow);
else if (etiquette.equals("blue"))
draw.setCol(Color.blue);
else if (etiquette.equals("green"))
draw.setCol(Color.green);
else if (etiquette.equals("pink"))
draw.setCol(Color.pink);
else if (etiquette.equals("cyan"))
draw.setCol(Color.cyan);
else if (etiquette.equals("lightGray"))
draw.setCol(Color.lightGray);
else if (etiquette.equals("red"))
draw.setCol(Color.red);
else if (etiquette.equals("darkGray"))
draw.setCol(Color.darkGray);
else if (etiquette.equals("magenta"))
draw.setCol(Color.magenta);
// compare a la gomme :
else if (evt.getSource().equals(gomme))
draw.setCol(Color.white);
// compare au crayon :
else if (evt.getSource().equals(crayon))
draw.setCol(Color.black);
}
}

// gère les cliques de la souris
class Mouse implements MouseListener, MouseMotionListener {
// quand on clic une fois sur le clic gauche
public void mouseClicked (MouseEvent evt) {
draw.execute(evt.getX(), evt.getY());
repaint();
}
public void mouseEntered (MouseEvent evt) {}
public void mouseExited (MouseEvent evt) {}
public void mousePressed (MouseEvent evt) {}
public void mouseReleased (MouseEvent evt) {}

public void mouseMoved(MouseEvent e) {}

// quand le clique gauche reste appuyer
public void mouseDragged(MouseEvent e) {
draw.execute(e.getX(), e.getY());
repaint();
}
}

// gère le choix de la forme du curseur
class ActionComb implements ActionListener {
public void actionPerformed (ActionEvent e) {
String result = (String) curseur.getSelectedItem();
draw.setCurseur(result);
}
}
}


 import java.awt.*;
import java.awt.event.*; // action listener
import javax.swing.*;
import java.awt.image.*;

public class Draw extends JPanel {

// curseur :
private Color curseurCol; // couleur du curseur
private String curseur; // forme du curseur
private int curseurWidth; // largeur du curseur

// Points :
private ColorPoint [] frame; // tableau contenant tout les points du dessin
private int coord; // sauvegarde du prochain index du tableau


public Draw () {
frame = new ColorPoint [2000000];
curseurCol = Color.black;
coord = 0;
curseurWidth = 30;
curseur = "Rond";
Cursor curs = creerCurseur();
this.setCursor(curs);
}

// méthode héritée, elle sert à peindre tout ce que contiendra le pannel, on l'appel a chaque changement via draw.repaint()
public void paintComponent (Graphics g) {
g.setColor(Color.white); // on repaint le fond en blanc
g.fillRect(0,0,(int)getSize().getWidth(), (int)getSize().getHeight()); // repeinte
for (int i = 0; i < frame.length; i++) { // affiche tout les points un par un
if (frame[i] != null) {
g.setColor(frame[i].getCol()); // prend la couleur du point a afficher
if (frame[i].getCurseur().equals("Carré"))
g.fillRect(frame[i].getX(), frame[i].getY(), frame[i].getWidth(), frame[i].getWidth()); // affiche le point
else if (frame[i].getCurseur().equals("Rond"))
g.fillOval(frame[i].getX(), frame[i].getY(), frame[i].getWidth(), frame[i].getWidth()); // affiche le point
}
}
}

// change la couleur du curseur puis actualise le curseur
public void setCol (Color col) {
curseurCol = col;
Cursor curs = creerCurseur();
setCursor(curs);
}

// change la taille du curseur puis actualise le curseur
public void setCurseurWidth (int x) {
curseurWidth = x;
Cursor curs = creerCurseur();
setCursor(curs);
}

// change la forme du curseur puis actualise le curseur
public void setCurseur (String curs) {
curseur = curs;
Cursor curs1 = creerCurseur();
setCursor(curs1);
}

// créer un nouveau curseur en fonction de la taille, de la couleur, et de la forme
public Cursor creerCurseur () {
BufferedImage image = new BufferedImage(curseurWidth,curseurWidth, BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
g.setColor(curseurCol);
if (curseur.equals("Rond"))
g.fillOval(0,0, curseurWidth, curseurWidth);
else if (curseur.equals("Carré"))
g.fillRect(0,0, curseurWidth, curseurWidth);
return Toolkit.getDefaultToolkit().createCustomCursor(image, new Point(curseurWidth/2,curseurWidth/2), "curseur perso");
}

// méthode appeler pour enregistrer un nouveau point dans le tableau de ColorPoint
public void execute (int x, int y) {
frame[coord] = new ColorPoint(x-curseurWidth/2, y-curseurWidth/2, curseurCol, curseurWidth, curseur); // met le point dans le tableau
coord ++; // augmente la coordonnée du tableau pour le point suivant
}
}


 import java.awt.*;
public class ColorPoint {
private Color couleur;
private int x;
private int y;
private int width;
private String curseur;

public ColorPoint (int x, int y, Color color, int w, String curs) {
couleur = color;
this.x = x;
this.y = y;
width = w;
curseur = curs;
}

//retour X point
public int getX () {
return x;
}

// retour Y point
public int getY () {
return y;
}

// retour forme du point
public String getCurseur() {
return curseur;
}

// retour largeur du point
public int getWidth() {
return width;
}

// retour couleur curseur
public Color getCol() {
return couleur;
}

}


merci par avance !
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
26 juin 2017 à 14:54
Ce n'est pas grand chose, une petite erreur d'étourderie facile à corriger (mais qui coûte très cher en débogage parce que ce n'est pas évident à trouver).

public class Panneau extends JPanel{

	private static Draw draw; // draw ne doit pas être static !
0
Hitsa Messages postés 2 Date d'inscription lundi 26 juin 2017 Statut Membre Dernière intervention 26 juin 2017 > KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024
26 juin 2017 à 14:56
oh mon dieu....... je n'aurai jamais trouvé, tu me sauves, dire qu'hier j'ai passer plus de 6h la dessus j'étais a deux doigts de devenir fou aha, merci beaucoup à toi ! a + (je met en resolu)
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015 > KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024
26 juin 2017 à 15:26
Remarque : je trouve ton code assez compliqué, en particulier je pense que ton
ColorPoint[] frame
est une mauvaise idée (très structurante pour ton programme).

Il aurait été plus simple de manipuler directement un BufferedImage, via sa méthode getGraphics() et de le réafficher au fur et à mesure de ses modifications.

Exemple :

public static void main(String[] args) {
    BufferedImage img = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
    Graphics graph = img.getGraphics();
    graph.setColor(Color.RED);

    Container draw = new Container() {
        public void paint(Graphics g) {
            g.drawImage(img, 0, 0, this);
        }
    };

    draw.addMouseListener(new MouseAdapter() {
        public void mouseClicked(MouseEvent e) {
            graph.fillRect(e.getX(), e.getY(), 5, 5);
            draw.repaint();
        }
    });

    JFrame frame = new JFrame();
    frame.setSize(500, 500);
    frame.setContentPane(draw);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}
0
Hits > KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024
26 juin 2017 à 15:46
je vais tester ca j'y avais pas penser mais ca a l'air mieux oui ! merci
0