У меня есть JScrollPane, панель содержимого которого представляет собой JXList. Когда я использую колесико мыши в списке, список перемещается по трем (3) элементам за раз. Это также работает для таблицы, независимо от высоты строки. Как я могу изменить это так, чтобы - независимо от платформы - как для списка, так и для таблицы расстояние прокрутки составляло ровно 1 элемент? Установка приращения блока не сокращает его, потому что некоторые строки в таблице имеют разную высоту.
Как заставить JScrollPane прокручивать 1 строку за шаг колесика мыши?
comment
@trashgod некоторое время не искал - кажется, что колесо действительно каким-то образом сопоставляется с unitIncrement и обрабатывает отдельные высоты строк, поэтому я ошибался в своих сомнениях. В конце концов, настройка прокручиваемой реализации может помочь :-)
- person kleopatra   schedule 09.07.2012
comment
См. Контроллер колесика мыши от camickr.
- person aterai   schedule 10.07.2012
comment
@aterai hach .. забыл об этом :-) Определенно правильный путь, подумайте о том, чтобы сделать свой комментарий ответом, чтобы получить несколько реальных голосов.
- person kleopatra   schedule 10.07.2012
comment
@kleopatra, спасибо за дополнительное объяснение. Я оставляю это вам.
- person aterai   schedule 11.07.2012
Ответы (2)
Из чистого интереса (и немного от скуки) я создал рабочий пример:
/**
* Scrolls exactly one Item a time. Works for JTable and JList.
*
* @author Lukas Knuth
* @version 1.0
*/
public class Main {
private JTable table;
private JList list;
private JFrame frame;
private final String[] data;
/**
* This is where the magic with the "just one item per scroll" happens!
*/
private final AdjustmentListener singleItemScroll = new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
// The user scrolled the List (using the bar, mouse wheel or something else):
if (e.getAdjustmentType() == AdjustmentEvent.TRACK){
// Jump to the next "block" (which is a row".
e.getAdjustable().setBlockIncrement(1);
}
}
};
public Main(){
// Place some random data:
Random rnd = new Random();
data = new String[120];
for (int i = 0; i < data.length; i++)
data[i] = "Set "+i+" for: "+rnd.nextInt();
for (int i = 0; i < data.length; i+=10)
data[i] = "<html>"+data[i]+"<br>Spacer!</html>";
// Create the GUI:
setupGui();
// Show:
frame.pack();
frame.setVisible(true);
}
private void setupGui(){
frame = new JFrame("Single Scroll in Swing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
frame.add(split);
// Add Data to the table:
table = new JTable(new AbstractTableModel() {
@Override
public int getRowCount() {
return data.length;
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data[rowIndex];
}
});
for (int i = 0; i < data.length; i+=10)
table.setRowHeight(i, 30);
JScrollPane scroll = new JScrollPane(table);
// Add out custom AdjustmentListener to jump only one row per scroll:
scroll.getVerticalScrollBar().addAdjustmentListener(singleItemScroll);
split.add(scroll);
list = new JList<String>(data);
scroll = new JScrollPane(list);
// Add out custom AdjustmentListener to jump only one row per scroll:
scroll.getVerticalScrollBar().addAdjustmentListener(singleItemScroll);
split.add(scroll);
}
public static void main(String[] agrs){
new Main();
}
}
Настоящая магия творится в пользовательском AdjustmentListener
, куда мы идем и увеличиваем текущую «позиция прокрутки» на один блок за раз. Это работает вверх и вниз и с разными размерами строк, как показано в примере.
Как отметил @kleopatra в комментариях, вы также можете использовать MouseWheelListener
только для переопределения поведения колесика мыши.
См. официальное руководство здесь.
person
Lukas Knuth
schedule
09.07.2012
Это чертовски круто. Бесконечно благодарен! Я имею в виду, что, конечно, где-то может быть .setScrollIncrement(int i), но так оно тоже работает. Небольшое отступление: этот код делает функцию страницы полосы прокрутки (щелчок по полосе за пределами ручки) прокручивать детские шаги, что не очень странно, учитывая, что ваш код устанавливает приращение блока равным 1 глобально. Есть ли способ просто изменить размер шага колесика мыши? Кроме того, можете ли вы порекомендовать книгу по Swing?
- person xmjx; 10.07.2012
Ах, надо еще немного прокомментировать. Мне было любопытно, почему setBlockIncrement(1) должен вызываться каждый раз при вызове AdjustmentListener, поэтому я деактивировал прослушиватель и вызывал setBlockIncrement(1) один раз во время создания панели прокрутки. Вот! Это тоже работает с тем же нежелательным побочным эффектом. Я не могу вспомнить, как это повлияло на мою офисную машину, поэтому я проверю это завтра на работе. Иногда мне не нравится Свинг. ;-)
- person xmjx; 10.07.2012
@xmjx для свинга, просто прочитайте учебные пособия, предоставленные sun/oracle. Специальной книги для этого я не читал. Swing довольно мощен, но это не самая маленькая графическая среда.
- person Lukas Knuth; 10.07.2012
-1 для перехода на низкий уровень, когда есть высокоуровневый подход ;-) WheelListener в scrollPane — это место, которое определяет количество прокрутки: по умолчанию это делается путем прокрутки количества единиц на отметку, как установлено панелью управления ОС. . Это место можно изменить, если требуется: просто сопоставьте метку только с одной единицей в пользовательском MouseWheelListener.
- person kleopatra; 10.07.2012
@kleopatra Я не знал об этом слушателе. Я обновил свой ответ соответственно, спасибо, что указали на это.
- person Lukas Knuth; 10.07.2012
@kleopatra Какую панель управления ОС вы имеете в виду? джконтроль? Потому что я не мог найти эту настройку там.
- person xmjx; 11.07.2012
@xmjx извините за неясность: я имел в виду настройку, сделанную изначально в ОС, в win, которая раньше называлась панелью управления, так что ничего общего с java
- person kleopatra; 11.07.2012
Слишком много кода для простого объяснения:
JLabel lblNewLabel = new JLabel("a lot of line of text...");
JScrollPane jsp = new JScrollPane(lblNewLabel);
jsp.getVerticalScrollBar().setUnitIncrement(10); //the bigger the number, more scrolling
frame.getContentPane().add(jsp, BorderLayout.CENTER);
person
Danylo Santos
schedule
11.09.2018