удаление ранее щелкнутого прямоугольника в java для потока [duplicate]

Сравнение строки в нечувствительном к регистру образом кажется чем-то тривиальным, но это не так. Я буду использовать Python 3, так как Python 2 недостаточно развит здесь.

Первое, что следует отметить, что конверсии case-remove в unicode не являются тривиальными. Существует текст, для которого text.lower() != text.upper().lower(), например "ß":

"ß".lower()
#>>> 'ß'

"ß".upper().lower()
#>>> 'ss'

Но скажем, вы хотели без лишних сравнений сравнить "BUSSE" и "Buße". Heck, вы, вероятно, также хотите сравнить "BUSSE" и "BUẞE" equal - это новая форма капитала. Рекомендуемым способом является использование casefold:

help(str.casefold)
#>>> Help on method_descriptor:
#>>>
#>>> casefold(...)
#>>>     S.casefold() -> str
#>>>     
#>>>     Return a version of S suitable for caseless comparisons.
#>>>

Не используйте только lower. Если casefold недоступен, выполнение .upper().lower() помогает (но только несколько).

Затем вы должны рассмотреть акценты. Если ваш рендерер шрифта хорош, вы, вероятно, думаете "ê" == "ê" - но это не так:

"ê" == "ê"
#>>> False

Это потому, что они на самом деле

import unicodedata

[unicodedata.name(char) for char in "ê"]
#>>> ['LATIN SMALL LETTER E WITH CIRCUMFLEX']

[unicodedata.name(char) for char in "ê"]
#>>> ['LATIN SMALL LETTER E', 'COMBINING CIRCUMFLEX ACCENT']

Самый простой способ дело в том, что это unicodedata.normalize. Вероятно, вы хотите использовать нормализацию NFKD, но не стесняйтесь проверить документацию. Затем выполняется

unicodedata.normalize("NFKD", "ê") == unicodedata.normalize("NFKD", "ê")
#>>> True

. Чтобы закончить, здесь это выражается в функциях:

import unicodedata

def normalize_caseless(text):
    return unicodedata.normalize("NFKD", text.casefold())

def caseless_equal(left, right):
    return normalize_caseless(left) == normalize_caseless(right)
1
задан MadProgrammer 7 February 2013 в 03:57
поделиться

2 ответа

Это относительно простая концепция (без обид).

Для начала не смешивайте свой код с JApplet и JFrame. Если вы хотите использовать свое приложение в этих двух средах, отделите логику на отдельный компонент (например, JPanel), который вы можете легко добавить к нему. Вы действительно не должны добавлять контейнер верхнего уровня в другой контейнер верхнего уровня (добавление апплета в фрейм) - это грязно.

Избегайте переопределения методов paint для контейнеров верхнего уровня (например, JApplet ) вместо этого используйте пользовательский компонент (например, JPanel) и переопределите его метод paintComponent.

В вашем примере вы должны называть super.paint, а не super.paintComponents. paint делает важную работу, вы не хотите ее пропускать, но вы должны использовать JComponent#paintComponent

MouseListener s, который должен быть добавлен к компонентам, которые вы заинтересованы в управлении событиями мыши. Поскольку clicked никогда не добавляется в какие-либо контейнеры, он никогда не получит события мыши.

Взгляните на

enter image description here [/g4]

public class SimplePaint03 {

    public static void main(String[] args) {
        new SimplePaint03();
    }

    public SimplePaint03() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new PaintPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class PaintPane extends JPanel {

        private List<Shape> grid;
        private List<Shape> fill;

        public PaintPane() {
            grid = new ArrayList<>(5);
            fill = new ArrayList<>(5);
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    for (Shape shape : grid) {
                        if (shape.contains(e.getPoint())) {
                            if (fill.contains(shape)) {
                                fill.remove(shape);
                            } else {
                                fill.add(shape);
                            }
                        }
                    }
                    repaint();
                }
            });

            int colWidth = 200 / 50;
            int rowHeight = 200 / 50;

            for (int row = 0; row < 50; row++) {
                for (int col = 0; col < 50; col++) {
                    grid.add(new Rectangle(colWidth * col, rowHeight * row, colWidth, rowHeight));
                }
            }

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); 
            Graphics2D g2d = (Graphics2D) g;
            g2d.setColor(Color.RED);
            for (Shape cell : fill) {
                g2d.fill(cell);
            }
            g2d.setColor(Color.BLACK);
            for (Shape cell : grid) {
                g2d.draw(cell);
            }
        }

    }

}

Дополнительно

Информация из одного цикла краски в другой не поддерживается. Вы должны перекрасить компонент точно так, как хотите. Это означает, что вам нужно будет сохранить список точек щелчка, которые можно перекрасить в любое время.

5
ответ дан MadProgrammer 24 August 2018 в 21:18
поделиться

Начните с чтения учебника Swing на пользовательской живописи .

Пользовательская покраска выполняется путем переопределения метода paintComponent () JPanel или JComponent (). Затем вы добавляете панель в JApplet.

Если вы хотите только нарисовать определенные квадраты, тогда вам понадобится Список, чтобы отслеживать, какие ячейки нужно рисовать. Затем каждый раз, когда вы перерисовываете компонент, вам нужно пройти через список и нарисовать ячейки.

Ваш MouseListener не будет расширять JApplet. Когда вы нажимаете на ячейку, вы обновляете список сверху, чтобы указать, что ячейка должна быть нарисована. Затем вы будете вызывать repaint () на панели, чтобы вызвать ваш код рисования.

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

2
ответ дан camickr 24 August 2018 в 21:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: