JProgressBar setValue не работает, пробовал также с SwingUtilities - PullRequest
3 голосов
/ 15 февраля 2012

Я реализовал JProgressBar в JTable. Я использовал рендерер для ProgressBar НЕ РЕДАКТОР.

Теперь я попытался реализовать заданное значение ProgressBar, но из-за того, что EDT не работает, поэтому я использовал SwingUtilties, но он также не работал.

ОЖИДАЕМОЕ ПОВЕДЕНИЕ - JProgressBar должен установить значение 80, в настоящее время он показывает только 0%

public class SkillSetTableProgressBarRenderer extends JProgressBar implements
        TableCellRenderer {

    public SkillSetTableProgressBarRenderer() {
        super(0, 100);
        super.setPreferredSize(new Dimension(100, 80));
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {

        final JProgressBar bar = (JProgressBar) value;

        if (bar.getString().equals("JAVA") || bar.getString().equals("SWING"))
            super.setString("Mellow");
        else
            super.setString("GOOD");

        setOpaque(true);
        table.setOpaque(true);

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                System.err.println("MAIN ANDER");
                setValue(80);
                bar.setValue(80);
            }
        });

        super.setStringPainted(true);
        super.setIndeterminate(true);
        super.setPreferredSize(new Dimension(140, 16));
        if (isSelected) {
            super.setBackground(table.getSelectionBackground());
            super.setForeground(table.getSelectionForeground());
            // this.setBackground(table.getSelectionBackground());
        } else {
            super.setForeground(table.getForeground());
            super.setBackground(Color.WHITE);
        }

        return this;
    }

}

Ответы [ 3 ]

3 голосов
/ 15 февраля 2012

Похоже, вы пытаетесь использовать ProgressBar в качестве CellRenderer.Одна вещь, которую вы должны знать, это то, что CellRenders only вызывается, когда ячейка рисуется, и установка значений в другие моменты не имеет никакого эффекта: это потому, что Swing использует шаблон flyweight для визуализаторов и, таким образом, повторно используетrenderer.

Чтобы получить желаемый эффект, вы должны

  • уведомить таблицу о том, что ячейка должна быть обновлена, например, путем обновления базовой модели (которая запустит необходимуюсобытия) и
  • установите все необходимые значения до возврата getTableCellRendererComponent, поэтому удалите invokeLater (метод получения вызывается в EDT, поэтому вам не нужнобеспокоиться о потоке там).
2 голосов
/ 16 февраля 2012

1) даже возможно, не создавайте JComponents внутри TableCellRenderer, ни re_create Object, Renderer предназначен только для форматирования содержимого ячейки

2) используйте SwingWorker для перемещения с прогрессом в JProgressBar (если у вас есть действительно важные причины, используйте Runnable#Tread)

пример о Runnable#Tread

enter image description here

import java.awt.Component;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class TableWithProgressBars {

    public static class ProgressRenderer extends JProgressBar implements TableCellRenderer {

        private static final long serialVersionUID = 1L;

        public ProgressRenderer(int min, int max) {
            super(min, max);
            this.setStringPainted(true);
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value,
                boolean isSelected, boolean hasFocus, int row, int column) {
            this.setValue((Integer) value);
            return this;
        }
    }
    private static final int maximum = 100;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TableWithProgressBars().createGUI();
            }
        });

    }

    public void createGUI() {
        final JFrame frame = new JFrame("Progressing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Integer[] oneRow = {0, 0, 0, 0};
        String[] headers = {"One", "Two", "Three", "Four"};
        Integer[][] data = {oneRow, oneRow, oneRow, oneRow, oneRow,};
        final DefaultTableModel model = new DefaultTableModel(data, headers);
        final JTable table = new JTable(model);
        table.setDefaultRenderer(Object.class, new ProgressRenderer(0, maximum));
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        frame.add(new JScrollPane(table));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        new Thread(new Runnable() {

            @Override
            public void run() {
                Object waiter = new Object();
                synchronized (waiter) {
                    int rows = model.getRowCount();
                    int columns = model.getColumnCount();
                    Random random = new Random(System.currentTimeMillis());
                    boolean done = false;
                    while (!done) {
                        int row = random.nextInt(rows);
                        int column = random.nextInt(columns);
                        Integer value = (Integer) model.getValueAt(row, column);
                        value++;
                        if (value <= maximum) {
                            model.setValueAt(value, row, column);
                            try {
                                waiter.wait(15);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        done = true;
                        for (row = 0; row < rows; row++) {
                            for (column = 0; column < columns; column++) {
                                if (!model.getValueAt(row, column).equals(maximum)) {
                                    done = false;
                                    break;
                                }
                            }
                            if (!done) {
                                break;
                            }
                        }
                    }
                    frame.setTitle("All work done");
                }
            }
        }).start();
    }
}
1 голос
/ 15 февраля 2012

Взгляните на учебник Swing table: средства визуализации и редакторы .Средство визуализации использует компонент для создания своего рода «штампа».Изменение компонента после этого не имеет никакого эффекта, так как компонент фактически не содержится в вашем пользовательском интерфейсе.Это одна из причин, по которой вы можете возвращать один и тот же компонент снова и снова, что было бы невозможно, если бы этот компонент фактически содержался в таблице.Все это объясняется в связанном учебном пособии.

Чтобы решить вашу проблему, просто удалите вызов метода SwingUtilities.invokeLater и верните JProgressBar, если задан правильный прогресс.

И еслиЯ правильно понимаю, у вас есть TableModel, содержащий JProgressBar.Я надеюсь, что для этого есть веская причина, поскольку это компонент пользовательского интерфейса, который обычно не следует включать в модель.Это основано на вашем

final JProgressBar bar = (JProgressBar) value;

вызове в рендерере.Я настоятельно рекомендую взглянуть на ваш TableModel, чтобы увидеть, можно ли этого избежать

...