10
votes

JDESKToppane Taille préférée définie par le contenu

J'ai essayé d'apprivoiser JDESKTOPPANE CODE> pour fonctionner bien avec une vitre de gui et de défilement redimensionnable, mais j'ai des problèmes qui le font. Il semble que sauf si le mode de glisser est décrit, em> le volet de bureau ne redimensionnera pas comme prévu (lorsqu'un cadre interne est glissé au-delà du bord du volet de bureau) et ne produisez donc pas de barres de défilement.

Entrez la description de l'image ici p>

suis-je en train de faire quelque chose de très stupide dans cette source? Ai-je manqué une approche beaucoup meilleure? P>

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane;

public class MDIPreferredSize {

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                final JDesktopPane dt = new JDesktopPane() {

                    @Override
                    public Dimension getPreferredSize() {
                        Dimension prefSize = super.getPreferredSize();
                        System.out.println("prefSize: " + prefSize);
                        // inititialize the max to the first normalized bounds
                        Rectangle max = getAllFrames()[0].getNormalBounds();
                        for (JInternalFrame jif : this.getAllFrames()) {
                            max.add(jif.getNormalBounds());
                        }
                        System.out.println("maxBounds(): "
                                + max);
                        int x1 = max.width + (max.x * 2) < prefSize.width
                                ? prefSize.width
                                : max.width + (max.x * 2);
                        int y1 = max.height + (max.y * 2) < prefSize.height
                                ? prefSize.height
                                : max.height + (max.y * 2);
                        System.out.println("x,y: "
                                + x1
                                + ","
                                + y1);
                        return new Dimension(x1, y1);
                    }
                };

                int xx = 5;
                int yy = 5;
                int vStep = 10;
                int yStep = 22;
                for (int ii = 0; ii < 3; ii++) {
                    JInternalFrame jif = new JInternalFrame(
                            "Internal Frame " + (ii + 1),
                            true,
                            true,
                            true);
                    dt.add(jif);
                    jif.setLocation(xx, yy);
                    xx += vStep;
                    yy += yStep;
                    jif.setSize(200, 75);
                    jif.setVisible(true);
                }

                /*final MouseListener mouseListener = new MouseAdapter() {

                    @Override
                    public void mouseReleased(MouseEvent e) {
                        dt.revalidate();
                    }
                };
                */
                final MouseMotionListener mouseMotionListener = new MouseMotionAdapter() {

                    @Override
                    public void mouseDragged(MouseEvent e) {
                        dt.revalidate();
                    }
                };
                for (JInternalFrame jif : dt.getAllFrames()) {
                    for (Component comp : jif.getComponents()) {
                        if (comp instanceof BasicInternalFrameTitlePane) {
                            //comp.addMouseListener(mouseListener);
                            comp.addMouseMotionListener(mouseMotionListener);
                        }
                    }
                }

                dt.setAutoscrolls(true);


                final JCheckBox outLineDragMode =
                        new JCheckBox("Outline Drag Mode");
                ActionListener dragModeListener = new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (outLineDragMode.isSelected()) {
                            dt.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
                        } else {
                            dt.setDragMode(JDesktopPane.LIVE_DRAG_MODE);
                        }
                    }
                };
                outLineDragMode.addActionListener(dragModeListener);

                JPanel gui = new JPanel(new BorderLayout());
                gui.add(outLineDragMode, BorderLayout.PAGE_START);
                gui.setBorder(new EmptyBorder(2, 3, 2, 3));
                gui.add(new JScrollPane(dt), BorderLayout.CENTER);

                JFrame f = new JFrame("DTP Preferred");
                f.add(gui);
                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See http://stackoverflow.com/a/7143398/418556 for demo.
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                f.setMinimumSize(f.getSize());

                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);

                printProperty("os.name");
                printProperty("java.version");
                printProperty("java.vendor");
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }

    public static void printProperty(String name) {
        System.out.println(name + ": \t" + System.getProperty(name));
    }
}


6 commentaires

J'ai testé votre code et je ne peux pas, même en mode de contour, que les barres de défilement apparaissent à moins que j'interagie avec la fenêtre principale. Je les ai arrangés deux fois mais cela semble être parce que je suis réussi à obtenir la fenêtre principale se rafraîchir. Peut-être aussi parce que j'ai redimensionné le cadre interne que j'ai traîné. Ayez le cadre, en mode, traversant un côté et redimensionner les barres de défilement apparaissent.


Huhh. Avec le lié ​​à Mkorbel (dans un commentaire maintenant supprimé), je soupçonne que c'est très la version / jre dépendant. Voir Modifier dans quelques instants .. Question éditée. Quelles sont les 3 propriétés où vous testez-vous?


J'ai testé avec Oracle Java 1.6.0_33, sous Ubuntu. On pense que je remarque que si je n'ai pas la barre de défilement, la fonctionnalité Autoscroll ne fonctionne pas. Je ne peux pas faire glisser le cadre plus loin que la bordure de cadre principal (la souris s'arrête à la différence de barres de défilement où elle ira plus loin).


Testé à nouveau avec 1.7.0_25 et je reproduis le même comportement, en mode Oultune, je reçois les barres de défilement lors de la traversée de la frontière, mais la fonctionnalité AutoScroll ne fonctionne toujours pas sans avoir des barres de défilement. Il y a une différence mais je doute que votre problème soit réellement lié à la version Java.


Voir aussi Créer un bureau virtuel défilable dans Swing au monde de Java.


La seule chose qui semble fonctionner est la solution de contournement de Ce bogue . Ajout du composant composant au jinternalframe et appelez dt.revalidate (); au lieu de valider le composant.


3 Réponses :


1
votes

Vous devriez pouvoir utiliser glisser la disposition pour gérer Le redimensionnement du volet de bureau à mesure que les composants sont traînés.


1 commentaires

Malheureusement, cela ne provoque pas d'amélioration ici. Les cadres sont minuscules et non redimensionnables, et s'ils sont maximisés, deviennent coincés en haut à gauche de la vitre (encore minuscule).



2
votes

Ajout d'un Mouselistener au Jinternalframe PANIÈLE TITRE EN tandis dans JDESKTOPPANE.LIVE_DRAG_MODE TO REVALIDATE THE Jdesktoppane après la libération est un moyen d'obtenir exactement le même comportement dans chaque mode. xxx

i supprimez-les dans le jdesktoppane.outline_drag_mode car il réagit déjà correctement.


2 commentaires

Joli. Cela fonctionne comme je m'attends dans le contour ou les modes de traînés de rendu standard. Peut-être que je vais ajouter un mousemotionlistener et voir si "Live glisser" bien au-delà des limites visibles du bureau actuel est pratique, mais pour le moment, cela fera très bien. :)


J'ai ajouté du code à la question qui prend en charge qu'un MousemotionListener pourrait également être utilisé ici.



1
votes

problème intéressant pour un samedi matin: -)

Pas de solution complète, juste quelques commentaires et un aperçu d'une approche alternative:

  • S'appuyant sur la souris / le mouvement / l'auditeur est incomplet en ce sens qu'il ne gère pas les mouvements contrôlés par le clavier
  • ComponentListeneur par internalframe à la rescousse: fonctionne bien si pas en mode de contour
  • En mode contour, la réévalidation ne peut pas fonctionner de toute façon, car elle s'appuie sur l'emplacement de cadre réel inchangé lors du glisser

    Donc, le vrai problème est le mode contour, doit

    • Tracez les limites intermédiaires du cadre traîné
    • Laissez le calcul de la préfecture du bureau prendre ces limites intermédiaires en compte
    • Le dessin du contour (inattendu, pour moi, voir ci-dessous [*])

      Le collaborateur responsable du déplacement de la trame est le desktopmanager.Drameframe: Sa mise en œuvre par défaut réinitialise les limites de la trame si elles ne sont pas en mode de contour ou ne conservent la trace de l'emplacement intermédiaire et dessinent le rectangle de plan si en mode de contour .

      L'idée évidente est un desktopmanager personnalisé qui remplace DragFrame:

      • laissez super faire ses affaires
      • en mode contour, obtenez l'emplacement intermédiaire de l'image et rangez-le quelque part sur le cadre lui-même, F.I. En tant que clientProperty

        maintenant une personne, f.i. Un PropertyChangelistener peut écouter les modifications de l'emplacement intermédiaire et déclencher un revalidate. Et le calcul de la préféquinisation du bureau peut rendre compte des limites intermédiaires en plus des limites réelles, quelque chose comme xxx

        utilisation: xxx

        [*] Le plan de la peinture de la peinture par défaut (à l'étendue qu'elle est invisible) - raison étant que la mise en œuvre par défaut utilise ... GetGraphics () ... Donc nous devons prendre en charge la peinture, FI dans un verre dédié (qui est fait par le code commenté) ou probablement mieux par un calaireui sur le bureau.

        Un verre brut, tout comme un POC qui ne clipse pas correctement et a quelques problèmes lorsque le cadre est replacé dans la section Visible: xxx

        Mise à jour

        Version avec Lechuyui - Nous laissons maintenant le nouveau comportement complet (enregistrement de l'auditeur, plan de peinture si nécessaire, en installant le gestionnaire) vers la décoration. Avantages:

        • Utilisation simplifiée
        • Un emplacement pour tous les détails sales

          la coucheui: xxx

          utilisation: xxx

          Il y a une légère prise (lire: "T Peut encore calculer comment résoudre le problème): Jlayer implémente défilable - sa mise en œuvre renvoie false pour tracksxx (si le composant décoré n'est pas défilé lui-même - JDESKToppane n'est pas), ce qui signifie que le bureau à l'intérieur d'un ScrollPane est toujours dimensionné. Sa préfsize qui montre la fenêtre de fenêtre grisâtre à la zone de fuite / inférieure si le scrollpane est plus grand.


0 commentaires