NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Dost divný problém s JTabbedPane

V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:10.5.2016 16:06

Zdravíčko, jak už jsem tu párkrát psal, já se dost šťourám do detailů a když solvnu jeden issue, objeví se další dva:)
O co se jedná: potřebuju udělat takovou malou kontingenční tabulku (dost jednoduchou a možná to ani není přímo kt, ale tak zní to vznešeněji:) ). Prostě výsledek má být, že je jeden JTabbedPane ve kterém je dalších xy JTabbedPanů a každý z nich obsahuje nějaký JPanel jako je vidět na funkčním examplu:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;

public class Plocha {
//###################-ATRIBUTY-###################
//==========KONSTANTNI ATRIBUTY TRIDY==========
//===========PROMENNE ATRIBUTY TRIDY===========
//========KONSTANTNI ATRIBUTY INSTANCI=========

    private final JTabbedPane jTabbedPane = new JTabbedPane();
//=========PROMENNE ATRIBUTY INSTANCI==========
    private JPanel panel;
    private JTabbedPane jtp;
//####################-STATIC-####################
//============STATICKY KONSTRUKTOR=============
//=========STATICKE PRISTUPOVE METODY==========
//==============STATICKE METODY================
//=================MAIN METODA=================

    public static void main(String[] args) {
        Plocha plocha = new Plocha();
    }
//###################-INSTANCE-###################
//=================KONSTRUKTOR=================

    public Plocha() {
        JFrame frame = new JFrame();
        frame.setSize(600, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(jTabbedPane);
        for (int i = 0; i < 5; i++) {
            jtp = new JTabbedPane();
            jTabbedPane.addTab(String.valueOf(i + 1) + ". skupina", jtp);
            for (int j = 0; j < 5; j++) {
                panel = new JPanel();
                jtp.addTab(String.valueOf(j + 1) + ". pod skupina", panel);
            }
            jtp.setTabPlacement(JTabbedPane.LEFT);
        }
        jTabbedPane.setUI(new javax.swing.plaf.basic.BasicTabbedPaneUI() {
            @Override
            protected int calculateTabHeight(int tabPlacement, int tabIndex, int fontHeight) {
                return 32;
            }

            @Override
            protected void paintTab(
                    Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex,
                    Rectangle iconRect, Rectangle textRect) {
                rects[tabIndex].width = jTabbedPane.getWidth() / rects.length;
                rects[tabIndex].x = (int) (tabIndex * rects[tabIndex].getWidth());
                super.paintTab(g, tabPlacement, rects, tabIndex, iconRect, textRect);
            }
        });
    }
//=============PRISTUPOVE METODY===============
//===================METODY====================
//###############-SOUKROME METODY-################
//=====STATICKE SOUKROME A POMOCNE METODY======
//==========SOUKROME A POMOCNE METODY==========
//############-SOUKROME KONSTRUKTORY-#############
//===============SOUKROME TRIDY================
//==============TESTOVACI METODY===============
}

Toto je v pořádku, funguje jak má.

A teď problém - pokud toto samé udělám v netbeansech tak, že si nejdřív nechám vygenerovat nový swingový JFrame, do něj vložím JTabbedPane viz další kód (zobrazuji jen atributy instancí a konstruktor, zbytek generuje netbeans):

*importy a hlavička třídy*
...
private JPanel panel;
    private JTabbedPane jtp;

    public NewJFrame() {
        initComponents();
        for (int i = 0; i < 5; i++) {
            jtp = new JTabbedPane();
            jTabbedPane1.addTab(String.valueOf(i + 1) + ". skupina", jtp);
            for (int j = 0; j < 5; j++) {
                panel = new JPanel();
                jtp.addTab(String.valueOf(j + 1) + ". pod skupina", panel);
            }
            jtp.setTabPlacement(JTabbedPane.LEFT);
        }
        jTabbedPane1.setUI(new javax.swing.plaf.basic.BasicTabbedPaneUI() {
            @Override
            protected int calculateTabHeight(int tabPlacement, int tabIndex, int fontHeight) {
                return 32;
            }

            @Override
            protected void paintTab(
                    Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex,
                    Rectangle iconRect, Rectangle textRect) {
                rects[tabIndex].width = jTabbedPane1.getWidth() / rects.length;
                rects[tabIndex].x = (int) (tabIndex * rects[tabIndex].getWidth());
                super.paintTab(g, tabPlacement, rects, tabIndex, iconRect, textRect);
            }
        });
    }
...
*vygenerovaný kód v netbeansech*

tak nastává krásný problém - na začátku mi nefunguje user interface (ui - to co nastavuju metodou setUI() ).

Prostě nejde kliknout na vrchní panely tak, jak se zobrazují, ale poprvé na ně jde kliknout jakoby byly bez nastaveného UIčka.
Trošku jsem to vyřešil tím, že jsem potom při každém zmačknutí tlačítka v podskupinách nastavil, že se musí jTabbedPane1 repaitnout. Funguje to, ale neznáte někdo jiné řešení? V mojem projektu se s tím setkávám ještě jednou, ale už nepomůže repaint, musím vždycky přepnout mezi vrchními skupinami a pak to už funguje normálně, ale musím mezi nimi přepnout, jako by neměly UI...

Takže ve zkratce.... jak lze nastavit UI třeba defaultně nebo jak udělat, že při vytváření a nastavení jednotlivých JPanelů nějak překreslit staré UI novým. JTabbedPane1.re­paint() na konci nepomáhá (proto sem píšu) a ani pack() na frame.

Je to trošku zmatené, ale snad chápete, o co se mi jedná, jestli ne, popíšu to step by step:)

Odpovědět
10.5.2016 16:06
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Lubor Pešek
Člen
Avatar
Odpovídá na Lubor Pešek
Lubor Pešek:10.5.2016 16:09

Ještě to doplním - kdy to přesně nefunguje: když kliknete na nějakou podskupinu a pak chcete kliknout na hlavní skupinu, tak pokud to nebude někde na začátku (podle původního UI) tak se nepřepnete do jiné skupiny a teď jsem si to zkoušel takhle přesně i v té samostatné třídě Plocha a taky to blbne:) takže jak to fixnout bez repaintu hlavního JTabbedPanu?

Editováno 10.5.2016 16:10
Nahoru Odpovědět
10.5.2016 16:09
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Atrament
Člen IT Redactor Gang
Avatar
Odpovídá na Lubor Pešek
Atrament:11.5.2016 13:56

Co smazat paintTab a overridnout calculateTabWidth

@Override
 protected int calculateTabWidth(int tabPlacement, int tabIndex, FontMetrics metrics) {
    return jTabbedePane.getWidth() / jTabbedPane.getTabCount();
 }

a nastav tomu panelu tabLayoutPolicy na SCROLL_TAB_LAYOUT jinak ti to bude občas házet do více řádků ty taby...

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
11.5.2016 13:56
Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:11.5.2016 13:59

jo, ale toto neřeší ten repaint, jen nastaví vrchní lištu jak má být-.- to je tak, když kód kopíruju a ještě na rychlo, díky za tu poznámku, máš naprostou pravdu.

Nicméně ten repaint stále blbne

Nahoru Odpovědět
11.5.2016 13:59
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Atrament
Člen IT Redactor Gang
Avatar
Odpovídá na Lubor Pešek
Atrament:11.5.2016 14:38

Jaký repaint blbne a jak? Mně to fungovalo dle očekávání ať jsem klikal jak jsem klikal, všechny taby okamžitě správně reagovali a fungoval i resize okna. Nebo jsem ještě něco přehlédl?

 
Nahoru Odpovědět
11.5.2016 14:38
Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:11.5.2016 14:40

a dělals to přes jednu třídu, kdes nastavoval všechny componenty zvlášť nebo sis naházel frame a tabbed pane podle netbeansového GUI editoru?

Nahoru Odpovědět
11.5.2016 14:40
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:11.5.2016 14:53

ty jo chlape máš můj nezkonalý respekt!!! sice jsem to neudělal přesně jak jsi mi psal ty, ale zavolal jsem tvoji metodu před metodou paintTab(). Už jen logicky to znamená, že ta metoda paintTab() nastavení volané tvojí metodou překryje, ale to je přesně ten refresh, který jsem myslel.

Jsi fakt borec, funguje to podle mých představ!! mockrát díkes

Nahoru Odpovědět
11.5.2016 14:53
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Atrament
Člen IT Redactor Gang
Avatar
Atrament:12.5.2016 0:37

Tak jestli ti to funguje, tak fajn, ale přece jenom mi to nedá se nezeptat - co tam furt máš s tím paintTab()? Vždyť je tam úplně zbytečný, to co v té metodě děláš je to samé čeho docílíš pomocí těch metod calculateTabWidth a calculateTabHeight. Já jsem vzal tvůj kód třídy Plocha, odstranil jsem zbytečné paintTab(), přidal metodu calculateTabWidth() a hotovo. Funguje jak má. Aspoň mi to teda připadá, že to funguje jak má, pokud je tam nějaké chybné chování, které nevidím, tak mi dej pls vědět.

 
Nahoru Odpovědět
12.5.2016 0:37
Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:12.5.2016 0:53

no tady toto je example, ale ve svém projektu mají jednotlivé taby rozdílnou velikost. A když už je v té metodě pole Rectanglů, tak to rovnou využívám v tom:)

Nahoru Odpovědět
12.5.2016 0:53
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Atrament
Člen IT Redactor Gang
Avatar
Odpovídá na Lubor Pešek
Atrament:12.5.2016 0:57

Aha, tak to je potom jasné. :)

 
Nahoru Odpovědět
12.5.2016 0:57
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 10.