Попытка использовать actionListener, чтобы перевернуть строку вверх дном

Из моего учебника: «Напишите приложение, которое расширяет JFrame и отображает фразу вверх ногами, когда пользователь нажимает кнопку. Фраза отображается нормально, когда пользователь снова нажимает кнопку».

В настоящее время у меня есть строка, которая рисуется с использованием метода paint() и графического объекта. Строка видна в кадре JUpsideDown, она перевернута и расположена примерно посередине панели. Я добавил свою кнопку и actionListener, но я думаю, что код в моем методе actionPerformed неверен, потому что я пытаюсь сделать отрицательный размер шрифта положительным, умножив его на -1, но, похоже, это не действует, когда я перекрашиваю . Позиционированная строка перемещается в положение x = 100 и y = 100, но строка по-прежнему перевернута.

Любое руководство приветствуется.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
@SuppressWarnings("serial")
public class JUpsideDown extends JFrame implements ActionListener
{
    int x = 350;
    int y = 100;
    int fontSize = -26;
    Font font = new Font("Serif", Font.PLAIN, fontSize);
    JButton press = new JButton("Flip Text");
    String label = "Look at this text, it will flip!";

    public JUpsideDown()
    {
        setTitle("JUpsideDown");
        setLayout(new FlowLayout());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(press);
        press.addActionListener(this);
    }

    public void paint(Graphics g)
    {
        super.paint(g);
        g.setFont(font);
        g.drawString(label, x, y);
    }

    public void actionPerformed(ActionEvent e)
    {
        fontSize = fontSize * -1;
        x = 100;
        y = 100;
        repaint();
    }

    public static void main(String[] args) 
    {
        JUpsideDown frame = new JUpsideDown();
        frame.setSize(450, 200);
        frame.setVisible(true);

    }

}

person P Stevens    schedule 19.11.2017    source источник
comment
ваш экземпляр шрифта не будет знать, когда и как вы меняете переменную fontSize класса JUpsideDown....   -  person guido    schedule 20.11.2017
comment
Я не думаю, что использование отрицательного размера шрифта перевернет текст, вместо этого вам нужно будет масштабировать контекст Graphics через отрицательное состояние, что также потребует дополнительного смещения для компенсации. Как правило, вы не хотите переопределять paint контейнера верхнего уровня, такого как JFrame, это может вызвать бесконечные проблемы, вместо этого вы должны начать с JPanel и вместо этого переопределить его метод paintComponent   -  person MadProgrammer    schedule 20.11.2017
comment
В этом примере показано использование отрицательной шкалы для переворачивания контекста Graphics   -  person MadProgrammer    schedule 20.11.2017
comment
Другим решением было бы просто повернуть контекст Graphics вокруг центра текста вместо этого.   -  person MadProgrammer    schedule 20.11.2017
comment
@MadProgrammer Для начала я использовал отрицательный шрифт, чтобы показать строку вверх ногами. Есть ли способ просто изменить переменную textSize на положительную, умножив ее внутри метода actionPerformed?   -  person P Stevens    schedule 20.11.2017
comment
@MadProgrammer Я перепробовал все, о чем до сих пор рассказывала моя книга. Я не думаю, что он прошел через любой из других вариантов, которые вы предложили.   -  person P Stevens    schedule 20.11.2017
comment
@PStevens Ну, это был удивительный и неожиданный результат, хотя за свои деньги я бы просто повернул контекст Graphics вокруг центра текста, но это я   -  person MadProgrammer    schedule 20.11.2017
comment
@MadProgrammer есть ли способ поместить paint () или paintComponent () внутри метода actionPerformed ()?   -  person P Stevens    schedule 20.11.2017
comment
@PStevens Нет, вы просто звоните repaint - ключевая проблема, с которой вы столкнулись сейчас, заключается в том, что вы на самом деле не обновляете состояние font, вы просто меняете некоторую переменную состояния.   -  person MadProgrammer    schedule 20.11.2017
comment
@MadProgrammer Я попытался снова объявить переменную шрифта внутри метода actionPerformed(), но тогда это была просто локальная переменная, которую метод paint() не видел, и я не могу установить шрифт графического объекта внутри метода actionPerformed().   -  person P Stevens    schedule 20.11.2017


Ответы (1)


Ваша логика верна, хотя вам нужно снова создать новый объект Font, который будет инкапсулировать новый fontsize. Это должно быть выполнено после нажатия кнопки внутри метода actionPerformed(). Таким образом, поведение приложения будет ожидаемым.

Ниже вы можете найти возможное решение:

public void actionPerformed(ActionEvent e)
    {
        fontSize = fontSize * -1;
        x = 100;
        y = 100;
        font = new Font("Serif", Font.PLAIN, fontSize); //added line
        repaint();
    }
person 0__1    schedule 20.11.2017
comment
font = new Font("Serif", Font.PLAIN, fontSize); //added line Это работает, и я думаю, что пробовал что-то очень похожее на это, но я попытался создать экземпляр нового объекта Font с именем font Font font = new Font("Serif", Font.PLAIN, fontSize); //added line Я думаю, что это то, что у меня было раньше, и, очевидно, это не сработает, потому что объект шрифта локализован для метода actionPerformed . Благодарю вас! - person P Stevens; 20.11.2017