JTable не обновляется немедленно при вызове fireTableRowsInserted () из прослушивателя действий - PullRequest
0 голосов
/ 24 мая 2011

У меня есть JTable, в который я вставляю строки, используя данные, найденные в Интернете. Когда я запускаю код, который заполняет список непосредственно из основной функции, я вижу, что каждая строка вставляется одновременно с вызовом fireTableRowsInserted - это то поведение, которое мне нужно. Однако, когда я запускаю тот же код из ActionListener JButton (во время ActionPreformed ()), таблица не обновляется, пока не завершится поток / событие. Я думаю, что проблема связана с потоками, но я не очень знаком с тем, как работают потоки, и не уверен, с чего начать. Вот пример проблемы:

public class Main { 
    static TestModel myTestModel = new TestModel(); 

    public static void main(String[] args) {
        JFrame  testFrame   = new JFrame();
        JTable  table       = new JTable(myTestModel);
        JButton button      = new JButton("Load");

        testFrame.getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
        testFrame.getContentPane().add(button, BorderLayout.PAGE_END);
        testFrame.pack();
        testFrame.setVisible(true);
        testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        button.addActionListener(new ActionListener(){
            @Override public void actionPerformed(ActionEvent e) {
                //When openURLStr is called here, the table in the JFrame doesn't add rows until
                // the function has exited.
                openURLStr("http://download.oracle.com/javase/1.4.2/docs/api/java/awt/Component.html", true);               
            }           
        });

        //When openURLStr is called here, the table in the JFrame adds rows at the same time the 
        // list in the table-model adds a row. (the desired behavoir)
        openURLStr("http://download.oracle.com/javase/1.4.2/docs/api/java/awt/Component.html", true);
        myTestModel.myArrayList.clear();
        myTestModel.fireTableDataChanged();
    }

    static class TestModel extends AbstractTableModel {
        ArrayList<String> myArrayList = new ArrayList<String>();

        @Override public int    getColumnCount()    { return(3);                    }
        @Override public int    getRowCount()       { return(myArrayList.size());   }
        @Override public Object getValueAt(int row, int col) {
            char c = '*';
            String rowStr = myArrayList.get(row);
            if ( rowStr.length() > col ) c = rowStr.charAt(col);
            return(c);
        }

        public boolean add(String line) {
            int row = myArrayList.size();
            if ( row < 100 ) {
                myArrayList.add(line);
                this.fireTableRowsInserted(row, row);               
                return(true);
            }
            else {
                return(false);
            }
        }       
    }

    private static void openURLStr(String urlStr, boolean lookForLinks) {
        try {
            URL                 url         = new URL(urlStr);
            InputStreamReader   isr         = new InputStreamReader(url.openConnection().getInputStream());
            BufferedReader      br          = new BufferedReader(isr);
            ArrayList<String>   linksFound  = new ArrayList<String>();

            if ( br != null ) {
                String strLine = br.readLine();
                //row added to table-model here: 
                boolean continueParse = myTestModel.add(strLine);

                //this code is mainly to induce more time between each addition of a line.
                while ( strLine != null && continueParse ) {
                    if ( lookForLinks && strLine != null ) {
                        String ahrefStr = "a href=\"";
                        int start_i = strLine.indexOf(ahrefStr) + ahrefStr.length();
                        if ( start_i > -1 ) {
                            int end_i = strLine.indexOf("\"", start_i+1);
                            if ( end_i > -1 && end_i > start_i ) {
                                linksFound.add(strLine.substring(start_i, end_i));
                            }
                        }
                    }
                    strLine = br.readLine();
                }
                br.close();
            }

            for ( String link : linksFound ) {
                openURLStr(link, false);
            }

        } catch (IOException e) {
        }
    }
}

1 Ответ

5 голосов
/ 24 мая 2011

ActionListener actionPerformed выполняется в потоке диспетчеризации событий , и он будет заблокирован вашим кодом внутри.Таким образом, графический интерфейс пользователя замораживается на это время, и обновления вообще не будут отображаться.

Попробуйте разделить «длительный» URL-вызов, например, в SwingWorker.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...