0

4 つのタブを持つ JTabbedPane があります。JtabbedPane は JLayeredPane にあります。1 番目と 4 番目のタブには、カスタム モデルを含む JTable が含まれています。各テーブルは 5 ~ 10 秒ごとに更新されます。
1 番目のタブがアクティブで、4 番目の JTable が更新された直後に、1 番目の 4 番目のコンテンツが表示されます。スクリーンショットを見てください。ここに画像の説明を入力 他のタブをクリックするか、ウィンドウを最小化すると、その奇妙な効果はなくなりました。4 番目のタブでそのテーブルが次に更新されるまで。
更新は Future<> オブジェクトを使用して行われます。Netbeans で Swing GUI ビルダーを使用したため、膨大な量のコードがあります。役立つ可能性のある作品を投稿します。
jTabbedPane を再検証しようとしましたが、効果がありませんでした。テーブルと jScrollPanes の両方で、不透明なプロパティが true に設定されています。そこで、SwingUtilities.invokeLater() を使用してみました。それは少し役に立ちました-最初のコンテンツの更新はうまくいきますが、後で-同じ問題です。

2 番目のテーブル モデルには、その内容を更新するメソッドがあります

public void setData(LinkedList<Object[]> __rows) {   
    NewDevsTableModel.__rows = __rows;
    fireTableDataChanged();
}

ここで使用されます(ここに SwingUtilities を追加しました

static class checkNew implements Callable<Boolean> {

@Override
public Boolean call() {
    ServiceMessage sm = ServiceMessage.getNewList();

    try {
        connect();
        os.write(sm.serialize());
        for (int i=0; i<10; i++) {
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {}

            if (is.available() > 0) {
                break;
            }

            if (i == 9) {
                disconnect();
                return false;
            }
        }

        byte[] actByte = new byte[is.available()];
        is.read(actByte);
        try {
            sm = ServiceMessage.Deserialize(actByte);   //may be there are no new devices
            if (sm.getType() == ServiceMessageType.NODATA) {
                MainWindow.jTabbedPane1.setEnabledAt(3, false);
                if (MainWindow.jTabbedPane1.getSelectedIndex() == 3) {
                    MainWindow.jTabbedPane1.setSelectedIndex(0);
                }
                return true;
            } else {
                return false;   //wrong answer type
            }
        } catch (ClassCastException | StreamCorruptedException e) {
            //remember selection and scroll
            final int scroll = MainWindow.jScrollPane3.getVerticalScrollBar().getValue();
            final int[] rows = MainWindow.newDevsTable.getSelectedRows();

            int col = MainWindow.devicesTable.getSelectedColumn();

            String[] parts = new String(actByte).split("\n");
            final LinkedList<Object[]> l = new LinkedList();
            for (int i=0; i<parts.length; i++) {
                String[] dev = parts[i].split(";", -1);
                String descr = dev[2];
                boolean iptype = (!dev[3].equals("-"));
                String address = dev[4];
                boolean atmtype = (dev[5].equals("+"));


                if (MainWindow.newDevsTable.getRowCount() >= (i+1)) {
                    if ((MainWindow.newDevsTable.getValueAt(i, 4) != null) && !MainWindow.newDevsTable.getValueAt(i, 4).equals("")) {
                        descr = MainWindow.newDevsTable.getValueAt(i, 4).toString();
                    }
                }
                Object[] o = {dev[0], dev[1], MainWindow.language[180], MainWindow.language[4], descr, iptype, address, atmtype}; 
                l.add(o);
            }

            if (!l.isEmpty()) {
                SwingUtilities.invokeLater( new Runnable() {
                    @Override
                    public void run() {
                        MainWindow.newDevsPanel.setVisible(true);
                        MainWindow.jTabbedPane1.setEnabledAt(3, true);
                        ((NewDevsTableModel)MainWindow.newDevsTable.getModel()).setData(l);   
                        ButtonColumn buttonColumn = new ButtonColumn(MainWindow.newDevsTable, addAction, 2, true);
                        buttonColumn = new ButtonColumn(MainWindow.newDevsTable, rejAction, 3, false);
                        //put selection back
                        for (int i=0; i<rows.length; i++) {
                            MainWindow.newDevsTable.addRowSelectionInterval(rows[i], rows[i]);
                        }
                        MainWindow.jScrollPane3.getVerticalScrollBar().setValue(scroll);
                    }
                });

            } else {
                MainWindow.jTabbedPane1.setEnabledAt(3, false);
                if (MainWindow.jTabbedPane1.getSelectedIndex() == 3) {
                    MainWindow.jTabbedPane1.setSelectedIndex(0);
                }
            }
            return true;
        }
    } catch (IOException e) {
        disconnect();              
        return false;
    } catch (ClassNotFoundException e) {
        return false;
    }
}
}

この方法でタスクを送信します

public static Future<Boolean> checkNewDevices() {        
    final Future<Boolean> task;        
    task = service.submit(new checkNew());
    return task;
}

自動的に更新するには、別のスレッドを使用します

public class CheckNewPassThread extends Thread {
int pause = 10000;

@Override
public void run() {
    for (;;) {
        HostConnection.checkNewDevices();
        try {
            Thread.sleep(pause);
        } catch (InterruptedException e) {}
    }
}
}

ウィンドウが開いたときに開始される

private void formWindowOpened(java.awt.event.WindowEvent evt) {                                  
    HostConnection.getData();        
    HostConnection.getDeviceAddress();
    RefreshData refreshThread = new RefreshData();
    refreshThread.start();
    new CheckNewPassThread().start();

}
4

1 に答える 1

0

OMG、問題は jTabbedPane.setEnabledAt(3, true) を既に有効なタブに呼び出すことにありました。スイングが魅力的

于 2012-11-09T05:31:43.627 に答える