最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - How to stop inner JScrollPanes from consuming mouse scroll wheel movements - Stack Overflow

programmeradmin3浏览0评论

I'm assembling a JPanel consisting of multiple JTables. Each JTable has an enclosing JScrollPane so the header values are displayed. The entire JPanel has an enclosing JScrollPane.

In this example, I made the outer JScrollPanepreferred size small enough for the vertical scroll bar to appear.

When I try to scroll using the mouse scroll wheel, I have to make sure my mouse pointer is outside of the JTable areas. It seems that the inner JScrollPanes are consuming the mouse scroll wheel movements.

I added the line:

scrollPane.setWheelScrollingEnabled(false);

on the inner JScrollPanes, but that wasn't sufficient.

How do I stop the inner JScrollPanes from consuming the mouse scroll wheel movements?

Here's a minimal reproducible example illustrating the problem.

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;

public class MultipleJTableExample implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new MultipleJTableExample());
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Multiple JTable Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createTablePanel(), BorderLayout.CENTER);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel createTablePanel() {
        JPanel outerPanel = new JPanel(new BorderLayout());

        JPanel panel = new JPanel(new GridBagLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.LINE_START;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(0, 0, 20, 0);

        gbc.gridx = 0;
        gbc.gridy = 0;
        Map<String, List<AnimalValue>> animalMap = new AnimalModel()
                .getAnimalMap();
        Set<String> mapSet = animalMap.keySet();
        Iterator<String> iterator = mapSet.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            List<AnimalValue> animalValues = animalMap.get(key);
            panel.add(createSubtablePanel(key, animalValues), gbc);
            gbc.gridy++;
        }

        Dimension d = panel.getPreferredSize();
        int height = d.height / 2;
        int width = d.width + 30;

        JScrollPane scrollPane = new JScrollPane(panel);
        JScrollBar scrollBar = scrollPane.getVerticalScrollBar();
        scrollBar.setMinimum(0);
        scrollBar.setMaximum(d.height);
        scrollBar.setBlockIncrement(32);
        scrollBar.setUnitIncrement(32);
        scrollPane.setPreferredSize(new Dimension(width, height));

        outerPanel.add(scrollPane, BorderLayout.CENTER);

        return outerPanel;
    }

    private JPanel createSubtablePanel(String key,
            List<AnimalValue> animalValues) {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));

        JLabel label = new JLabel(key);
        label.setFont(panel.getFont().deriveFont(Font.BOLD, 20f));
        panel.add(label, BorderLayout.NORTH);

        AVTableModel tableModel = new AVTableModel();
        tableModel.addColumns();
        tableModel.addRows(animalValues);

        JTable table = new JTable(tableModel);
        table.setAutoCreateRowSorter(true);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        TableColumnModel columnModel = table.getColumnModel();
        columnModel.getColumn(0).setPreferredWidth(150);
        columnModel.getColumn(1).setPreferredWidth(60);
        columnModel.getColumn(2).setPreferredWidth(100);
        columnModel.getColumn(3).setPreferredWidth(60);
        columnModel.getColumn(4).setPreferredWidth(100);
        columnModel.getColumn(5).setPreferredWidth(100);
        Dimension d = table.getPreferredSize();
        d.width = 570;
        table.setPreferredSize(d);
        table.setPreferredScrollableViewportSize(
                new Dimension(d.width, d.height));

        columnModel.getColumn(1).setCellRenderer(new CenterRenderer());
        columnModel.getColumn(2).setCellRenderer(new CenterRenderer());
        columnModel.getColumn(3).setCellRenderer(new PercentRenderer());
        columnModel.getColumn(4).setCellRenderer(new MoneyRenderer("%,d"));
        columnModel.getColumn(5).setCellRenderer(new MoneyRenderer("%,d"));

        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setWheelScrollingEnabled(false);

        panel.add(scrollPane, BorderLayout.CENTER);

        return panel;
    }

    public class CenterRenderer extends DefaultTableCellRenderer {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {
            JLabel label = (JLabel) super.getTableCellRendererComponent(table,
                    value, isSelected, hasFocus, row, column);
            label.setHorizontalAlignment(JLabel.CENTER);
            return label;
        }

    }

    public class MoneyRenderer extends DefaultTableCellRenderer {

        private static final long serialVersionUID = 1L;

        private final String formatter;

        public MoneyRenderer(String formatter) {
            this.formatter = formatter;
        }

        @Override
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {
            JLabel label = (JLabel) super.getTableCellRendererComponent(table,
                    value, isSelected, hasFocus, row, column);
            String s = "";
            if (value instanceof Double) {
                s = String.format(formatter, (double) value);
            } else {
                s = String.format(formatter, (int) value);
            }

            label.setText("$" + s + " ");
            label.setHorizontalAlignment(JLabel.TRAILING);
            return label;
        }

    }

    public class PercentRenderer extends DefaultTableCellRenderer {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {
            JLabel label = (JLabel) super.getTableCellRendererComponent(table,
                    value, isSelected, hasFocus, row, column);
            label.setText(value.toString() + "%");
            label.setHorizontalAlignment(JLabel.CENTER);
            return label;
        }

    }

    public class AVTableModel extends DefaultTableModel {

        private static final long serialVersionUID = 1L;

        public AVTableModel() {
            super();
        }

        public void addColumns() {
            addColumn("Subtype");
            addColumn("Count");
            addColumn("Age in months");
            addColumn("Health");
            addColumn("Current value");
            addColumn("Total value");
        }

        public void addRows(List<AnimalValue> animalValues) {
            for (AnimalValue animalValue : animalValues) {
                Object[] rowData = new Object[this.getColumnCount()];
                rowData[0] = animalValue.getSubType();
                int count = animalValue.getCount();
                rowData[1] = count;
                rowData[2] = animalValue.getAge();
                rowData[3] = animalValue.getHealth();
                int value = animalValue.getValue();
                rowData[4] = value / count;
                rowData[5] = value;
                addRow(rowData);
            }
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            switch (columnIndex) {
            case 0:
                return String.class;
            default:
                return Integer.class;
            }
        }

    }

    public class AnimalModel {

        private Map<String, List<AnimalValue>> animalMap;

        public AnimalModel() {
            this.animalMap = new HashMap<>();
            List<AnimalValue> animalValues = new ArrayList<>();
            animalValues.add(new AnimalValue(20, 12, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 11, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 10, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 9, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 8, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 7, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 6, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 5, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 4, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 3, 100, "chicken"));
            animalMap.put("Chicken coop 1", animalValues);

            animalValues = new ArrayList<>();
            animalValues.add(new AnimalValue(20, 12, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 11, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 10, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 9, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 8, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 7, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 6, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 5, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 4, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 3, 100, "chicken"));
            animalMap.put("Chicken coop 2", animalValues);

            animalValues = new ArrayList<>();
            animalValues.add(new AnimalValue(20, 12, 100, "cow"));
            animalValues.add(new AnimalValue(20, 11, 100, "cow"));
            animalValues.add(new AnimalValue(20, 10, 100, "cow"));
            animalValues.add(new AnimalValue(20, 9, 100, "cow"));
            animalValues.add(new AnimalValue(20, 8, 100, "cow"));
            animalValues.add(new AnimalValue(20, 7, 100, "cow"));
            animalValues.add(new AnimalValue(20, 6, 100, "cow"));
            animalValues.add(new AnimalValue(20, 5, 100, "cow"));
            animalValues.add(new AnimalValue(20, 4, 100, "cow"));
            animalValues.add(new AnimalValue(20, 3, 100, "cow"));
            animalMap.put("Cow barn", animalValues);
        }

        public Map<String, List<AnimalValue>> getAnimalMap() {
            return animalMap;
        }

    }

    public class AnimalValue {

        private final int age, count, health;

        private final String subType, type;

        public AnimalValue(int count, int age, int health, String subType) {
            this.count = count;
            this.age = age;
            this.health = health;
            this.type = formatType(subType);
            this.subType = formatSubType(subType);
        }

        private String formatType(String type) {
            String output = type.toLowerCase();
            int pos = output.lastIndexOf("_");
            if (pos >= 0) {
                output = output.substring(0, pos);
            }

            return output;
        }

        private String formatSubType(String subType) {
            String output = subType.toLowerCase();
            int pos = output.lastIndexOf("_");
            if (pos >= 0) {
                output = output.substring(pos + 1);
            }
            char u = Character.toUpperCase(output.charAt(0));

            return "" + u + output.substring(1);
        }

        public int getValue() {
            switch (type) {
            case "chicken":
                if (subType.equals("Chicken")) {
                    return calculateValue(count, age, 6, health, 5, 25);
                } else {
                    return calculateValue(count, age, 6, health, 5, 20);
                }
            case "cow":
                return calculateValue(count, age, 18, health, 150, 1500);
            default:
                return 0;
            }
        }

        private int calculateValue(int count, int age, int maturity, int health,
                int minValue, int maxValue) {
            int maxAge = Math.min(maturity, age);
            return (int) (((double) maxAge * (maxValue - minValue) / maturity
                    + minValue) * health / 100.0 * count);
        }

        public int getAge() {
            return age;
        }

        public int getCount() {
            return count;
        }

        public int getHealth() {
            return health;
        }

        public String getSubType() {
            return subType;
        }

    }

}

I'm assembling a JPanel consisting of multiple JTables. Each JTable has an enclosing JScrollPane so the header values are displayed. The entire JPanel has an enclosing JScrollPane.

In this example, I made the outer JScrollPanepreferred size small enough for the vertical scroll bar to appear.

When I try to scroll using the mouse scroll wheel, I have to make sure my mouse pointer is outside of the JTable areas. It seems that the inner JScrollPanes are consuming the mouse scroll wheel movements.

I added the line:

scrollPane.setWheelScrollingEnabled(false);

on the inner JScrollPanes, but that wasn't sufficient.

How do I stop the inner JScrollPanes from consuming the mouse scroll wheel movements?

Here's a minimal reproducible example illustrating the problem.

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;

public class MultipleJTableExample implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new MultipleJTableExample());
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Multiple JTable Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createTablePanel(), BorderLayout.CENTER);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel createTablePanel() {
        JPanel outerPanel = new JPanel(new BorderLayout());

        JPanel panel = new JPanel(new GridBagLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.LINE_START;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(0, 0, 20, 0);

        gbc.gridx = 0;
        gbc.gridy = 0;
        Map<String, List<AnimalValue>> animalMap = new AnimalModel()
                .getAnimalMap();
        Set<String> mapSet = animalMap.keySet();
        Iterator<String> iterator = mapSet.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            List<AnimalValue> animalValues = animalMap.get(key);
            panel.add(createSubtablePanel(key, animalValues), gbc);
            gbc.gridy++;
        }

        Dimension d = panel.getPreferredSize();
        int height = d.height / 2;
        int width = d.width + 30;

        JScrollPane scrollPane = new JScrollPane(panel);
        JScrollBar scrollBar = scrollPane.getVerticalScrollBar();
        scrollBar.setMinimum(0);
        scrollBar.setMaximum(d.height);
        scrollBar.setBlockIncrement(32);
        scrollBar.setUnitIncrement(32);
        scrollPane.setPreferredSize(new Dimension(width, height));

        outerPanel.add(scrollPane, BorderLayout.CENTER);

        return outerPanel;
    }

    private JPanel createSubtablePanel(String key,
            List<AnimalValue> animalValues) {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));

        JLabel label = new JLabel(key);
        label.setFont(panel.getFont().deriveFont(Font.BOLD, 20f));
        panel.add(label, BorderLayout.NORTH);

        AVTableModel tableModel = new AVTableModel();
        tableModel.addColumns();
        tableModel.addRows(animalValues);

        JTable table = new JTable(tableModel);
        table.setAutoCreateRowSorter(true);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        TableColumnModel columnModel = table.getColumnModel();
        columnModel.getColumn(0).setPreferredWidth(150);
        columnModel.getColumn(1).setPreferredWidth(60);
        columnModel.getColumn(2).setPreferredWidth(100);
        columnModel.getColumn(3).setPreferredWidth(60);
        columnModel.getColumn(4).setPreferredWidth(100);
        columnModel.getColumn(5).setPreferredWidth(100);
        Dimension d = table.getPreferredSize();
        d.width = 570;
        table.setPreferredSize(d);
        table.setPreferredScrollableViewportSize(
                new Dimension(d.width, d.height));

        columnModel.getColumn(1).setCellRenderer(new CenterRenderer());
        columnModel.getColumn(2).setCellRenderer(new CenterRenderer());
        columnModel.getColumn(3).setCellRenderer(new PercentRenderer());
        columnModel.getColumn(4).setCellRenderer(new MoneyRenderer("%,d"));
        columnModel.getColumn(5).setCellRenderer(new MoneyRenderer("%,d"));

        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setWheelScrollingEnabled(false);

        panel.add(scrollPane, BorderLayout.CENTER);

        return panel;
    }

    public class CenterRenderer extends DefaultTableCellRenderer {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {
            JLabel label = (JLabel) super.getTableCellRendererComponent(table,
                    value, isSelected, hasFocus, row, column);
            label.setHorizontalAlignment(JLabel.CENTER);
            return label;
        }

    }

    public class MoneyRenderer extends DefaultTableCellRenderer {

        private static final long serialVersionUID = 1L;

        private final String formatter;

        public MoneyRenderer(String formatter) {
            this.formatter = formatter;
        }

        @Override
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {
            JLabel label = (JLabel) super.getTableCellRendererComponent(table,
                    value, isSelected, hasFocus, row, column);
            String s = "";
            if (value instanceof Double) {
                s = String.format(formatter, (double) value);
            } else {
                s = String.format(formatter, (int) value);
            }

            label.setText("$" + s + " ");
            label.setHorizontalAlignment(JLabel.TRAILING);
            return label;
        }

    }

    public class PercentRenderer extends DefaultTableCellRenderer {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {
            JLabel label = (JLabel) super.getTableCellRendererComponent(table,
                    value, isSelected, hasFocus, row, column);
            label.setText(value.toString() + "%");
            label.setHorizontalAlignment(JLabel.CENTER);
            return label;
        }

    }

    public class AVTableModel extends DefaultTableModel {

        private static final long serialVersionUID = 1L;

        public AVTableModel() {
            super();
        }

        public void addColumns() {
            addColumn("Subtype");
            addColumn("Count");
            addColumn("Age in months");
            addColumn("Health");
            addColumn("Current value");
            addColumn("Total value");
        }

        public void addRows(List<AnimalValue> animalValues) {
            for (AnimalValue animalValue : animalValues) {
                Object[] rowData = new Object[this.getColumnCount()];
                rowData[0] = animalValue.getSubType();
                int count = animalValue.getCount();
                rowData[1] = count;
                rowData[2] = animalValue.getAge();
                rowData[3] = animalValue.getHealth();
                int value = animalValue.getValue();
                rowData[4] = value / count;
                rowData[5] = value;
                addRow(rowData);
            }
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            switch (columnIndex) {
            case 0:
                return String.class;
            default:
                return Integer.class;
            }
        }

    }

    public class AnimalModel {

        private Map<String, List<AnimalValue>> animalMap;

        public AnimalModel() {
            this.animalMap = new HashMap<>();
            List<AnimalValue> animalValues = new ArrayList<>();
            animalValues.add(new AnimalValue(20, 12, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 11, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 10, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 9, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 8, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 7, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 6, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 5, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 4, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 3, 100, "chicken"));
            animalMap.put("Chicken coop 1", animalValues);

            animalValues = new ArrayList<>();
            animalValues.add(new AnimalValue(20, 12, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 11, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 10, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 9, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 8, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 7, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 6, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 5, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 4, 100, "chicken"));
            animalValues.add(new AnimalValue(20, 3, 100, "chicken"));
            animalMap.put("Chicken coop 2", animalValues);

            animalValues = new ArrayList<>();
            animalValues.add(new AnimalValue(20, 12, 100, "cow"));
            animalValues.add(new AnimalValue(20, 11, 100, "cow"));
            animalValues.add(new AnimalValue(20, 10, 100, "cow"));
            animalValues.add(new AnimalValue(20, 9, 100, "cow"));
            animalValues.add(new AnimalValue(20, 8, 100, "cow"));
            animalValues.add(new AnimalValue(20, 7, 100, "cow"));
            animalValues.add(new AnimalValue(20, 6, 100, "cow"));
            animalValues.add(new AnimalValue(20, 5, 100, "cow"));
            animalValues.add(new AnimalValue(20, 4, 100, "cow"));
            animalValues.add(new AnimalValue(20, 3, 100, "cow"));
            animalMap.put("Cow barn", animalValues);
        }

        public Map<String, List<AnimalValue>> getAnimalMap() {
            return animalMap;
        }

    }

    public class AnimalValue {

        private final int age, count, health;

        private final String subType, type;

        public AnimalValue(int count, int age, int health, String subType) {
            this.count = count;
            this.age = age;
            this.health = health;
            this.type = formatType(subType);
            this.subType = formatSubType(subType);
        }

        private String formatType(String type) {
            String output = type.toLowerCase();
            int pos = output.lastIndexOf("_");
            if (pos >= 0) {
                output = output.substring(0, pos);
            }

            return output;
        }

        private String formatSubType(String subType) {
            String output = subType.toLowerCase();
            int pos = output.lastIndexOf("_");
            if (pos >= 0) {
                output = output.substring(pos + 1);
            }
            char u = Character.toUpperCase(output.charAt(0));

            return "" + u + output.substring(1);
        }

        public int getValue() {
            switch (type) {
            case "chicken":
                if (subType.equals("Chicken")) {
                    return calculateValue(count, age, 6, health, 5, 25);
                } else {
                    return calculateValue(count, age, 6, health, 5, 20);
                }
            case "cow":
                return calculateValue(count, age, 18, health, 150, 1500);
            default:
                return 0;
            }
        }

        private int calculateValue(int count, int age, int maturity, int health,
                int minValue, int maxValue) {
            int maxAge = Math.min(maturity, age);
            return (int) (((double) maxAge * (maxValue - minValue) / maturity
                    + minValue) * health / 100.0 * count);
        }

        public int getAge() {
            return age;
        }

        public int getCount() {
            return count;
        }

        public int getHealth() {
            return health;
        }

        public String getSubType() {
            return subType;
        }

    }

}
Share Improve this question asked Feb 15 at 21:50 Gilbert Le BlancGilbert Le Blanc 51.5k6 gold badges72 silver badges116 bronze badges 4
  • t's OK to Ask and Answer Your Own Questions – Gilbert Le Blanc Commented Feb 15 at 22:10
  • 1 The better solution is never to place a JScrollPane inside another JScrollPane, as it creates usability issues. In the case of this example, making the JTables and their JScrollPanes children of a JSplitPane would solve the problem without the need for nested JScrollPanes. – VGR Commented Feb 16 at 1:52
  • @VGR: This is an example with three animal groups. The real JPanel can have a dozen animal groups or more. I don't see how a JSplitPane helps. – Gilbert Le Blanc Commented Feb 16 at 3:57
  • 1 Consider using a tabbed pane with one table in each tab. – Just another Java programmer Commented Feb 16 at 10:42
Add a comment  | 

2 Answers 2

Reset to default 1

There may be a way to use a JLayer that transfers MouseWheelEvent to the inner JScrollPane to the outer JScrollPane.

// outerPanel.add(scrollPane, BorderLayout.CENTER);
outerPanel.add(new JLayer<>(scrollPane, new WheelScrollLayerUI()));
import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.event.MouseWheelEvent;
import javax.swing.JComponent;
import javax.swing.JLayer;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.plaf.LayerUI;

public class WheelScrollLayerUI extends LayerUI<JScrollPane> {
  @Override public void installUI(JComponent c) {
    super.installUI(c);
    if (c instanceof JLayer) {
      ((JLayer<?>) c).setLayerEventMask(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
    }
  }

  @Override public void uninstallUI(JComponent c) {
    if (c instanceof JLayer) {
      ((JLayer<?>) c).setLayerEventMask(0);
    }
    super.uninstallUI(c);
  }

  @Override protected void processMouseWheelEvent(
        MouseWheelEvent e, JLayer<? extends JScrollPane> l) {
    Component c = e.getComponent();
    JScrollPane outer = l.getView();
    if (!c.equals(outer) && c instanceof JScrollPane) {
      if (!((JScrollPane) c).isWheelScrollingEnabled()) {
        outer.dispatchEvent(SwingUtilities.convertMouseEvent(c, e, outer));
      }
    }
  }
}

Setting scrollPane.setWheelScrollingEnabled(false); isn't sufficient, as you've discovered. The inner JScrollPane MouseWheelListeners have to be removed.

Add these lines near the end of the createSubtablePanel method:

    scrollPane.setWheelScrollingEnabled(false);
    MouseWheelListener[] listeners = scrollPane.getMouseWheelListeners();
    for (MouseWheelListener listener : listeners) {
        scrollPane.removeMouseWheelListener(listener);
    }

These lines will remove the MouseWheelListeners on the inner JScrollPanes that are consuming the mouse scroll wheel movements.

发布评论

评论列表(0)

  1. 暂无评论