2017-02-03 6 views
-1

У меня есть выпадающая строка и кнопка. При нажатии на кнопку будет выбран первый элемент списка со списком (индекс 0). Но хотя combo.getSelectedIndex() был изменен (я вижу, что он изменился при отладке), в пользовательском интерфейсе я не вижу его. Зачем?Java SWING - JComboBox не меняет выбор в пользовательском интерфейсе, когда setSelectedIndex() называется

исполняемый пример:

package com.WindThunderStudio.TableWithComboBox; 

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.DefaultCellEditor; 
import javax.swing.JButton; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.table.TableColumn; 

public class TC extends JFrame{ 
    JComboBox<String> combo; 
    JTable table; 
    public TC(){ 
     begin(); 
    } 
    public void begin(){ 
     setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     setTitle("nothing."); 
     DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(options); 
     combo = new JComboBox<>(model); 
     JTable table = new JTable(new Object[2][2], new String[]{"Column One", "Column Two"}); 
     TableColumn col0 = table.getColumnModel().getColumn(0); 
     col0.setCellEditor(new DefaultCellEditor(combo)); 

     JButton button = new JButton("Clear"); 
     button.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       combo.setSelectedIndex(0); 
      } 
     }); 


     getContentPane().setLayout(null); 
//  getContentPane().setLayout(new MigLayout()); 

     setPreferredSize(new Dimension(500,500)); 
     JScrollPane sp = new JScrollPane(table); 
     sp.setBounds(0,0,300,100); 
     getContentPane().add(sp); 
     button.setBounds(300,100,200,200); 
     getContentPane().add(button); 
     pack(); 
     setVisible(true); 
    } 

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

      @Override 
      public void run() { 
       TC tc = new TC(); 

      } 

     }); 
    } 
} 

У меня есть поиск и в Google, как ни странно, я вижу более сложные случаи, когда «не обновляет интерфейс» часть схожа, но мой случай проще.

Я прочитал DOC говоря:

Что-то еще, чтобы следить за - даже для нередактируемых комбинированных окон - это обеспечения того, чтобы пользовательский список моделей пожаров ваших событий данных, когда данные бокса комб или изменения состояния , Даже неизменяемые модели с комбинированными полями, данные которых не изменяются, никогда не изменяются, при сбое выбора должно произойти событие списка данных (событие CONTENTS_CHANGED ). Один из способов получить событие с данными списка - бесплатный код для стрельбы - это создать подкласс класса AbstractListModel.

Но я думаю, что я здесь, потому что DefaultComboBoxModel распространяется AbstractListModel.

Эта линия не работает.

combo.setSelectedItem(combo.getModel().getElementAt(0)); 

Итак, есть ли какой-то намек на меня? Это должно иметь какое-то отношение к рендереру, но я не знаю, что я сделал неправильно. BasicComboboxRenderer не реагирует на изменения комбо selectedIndex?

+0

Вы пробовали переименовать(); после изменения выбора? – Mark

+0

'repaint()', 'updateUI()' не работает. Я помещал их в 'actionPerformed()' часть. Я считаю их ненужными. – FaithReaper

+0

Редактор используется только для редактирования значения в ячейке. Чтобы сделать то, что вам нужно, вам нужно обновить модель таблицы. –

ответ

4

Как я уже сказал, вам необходимо обновить модель.

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.DefaultCellEditor; 
import javax.swing.DefaultComboBoxModel; 
import javax.swing.JButton; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.table.TableColumn; 

public class TC extends JFrame{ 
    JComboBox<String> combo; 
    JTable table; 
    public TC(){ 
     begin(); 
    } 
    public void begin(){ 
     setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     setTitle("nothing."); 
     DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(new String[] {"One", "Two", "Three"}); 
     combo = new JComboBox<>(model); 
     table = new JTable(new Object[2][2], new String[] {"Column One", "Column Two"}); 
     TableColumn col0 = table.getColumnModel().getColumn(0); 
     col0.setCellEditor(new DefaultCellEditor(combo)); 

     JButton button = new JButton("Clear"); 
     button.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (int i = 0; i < table.getModel().getRowCount(); i++) { 
        table.setValueAt(combo.getModel().getElementAt(0), i, 0); 
       } 
      } 
     }); 


     getContentPane().setLayout(null); 
//  getContentPane().setLayout(new MigLayout()); 

     setPreferredSize(new Dimension(500,500)); 
     JScrollPane sp = new JScrollPane(table); 
     sp.setBounds(0,0,300,100); 
     getContentPane().add(sp); 
     button.setBounds(300,100,200,200); 
     getContentPane().add(button); 
     pack(); 
     setVisible(true); 
    } 

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

      @Override 
      public void run() { 
       TC tc = new TC(); 

      } 

     }); 
    } 
} 
+0

Я не считаю это правильным. Я хочу обновить таблицу по реальному значению в каждой ячейке, но вы отвечаете на заполнение таблицы «null». Теперь то, что я вижу во всей таблице, пуст. Что делать, если я хочу, чтобы сброс значения первого списка со списком «один» и «два»? – FaithReaper

+0

@FaithReaper Я исправил свой ответ. –

+0

Это прекрасно, спасибо! Итак, если я это хорошо понимаю, рендеринг ячейки, если это Combobox, не будет обновляться, потому что обновление будет контролироваться таблицей? – FaithReaper