Способы удаления JLabels?

#java #swing #transparency #jlabel

#java #swing #прозрачность #jlabel

Вопрос:

У меня возникли проблемы с игрой, которую я создаю. Я пытаюсь отключить JLabel, используя таймер. До сих пор мне удавалось установить JLabel как прозрачный, и я был в состоянии создать работающий таймер. Но почему-то я не могу объединить их вместе. Я могу установить фон JLabel на

 l.setBackground(new Color(0, 0, 0, 200));
  

(l желателен JLabel для изменения цвета, конечно)
и это работает. JLabel прозрачен.
Но мне не удалось установить это в таймер, чтобы цвет померк:

 public static void fadeLabel(JLabel lab, int steps, int target) {
    class fade extends Thread {
        public void run() {
            Timer t = new Timer(10, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println(lab.getBackground().getAlpha());
                    lab.setBackground(new 
                    Color(lab.getBackground().getRed(), 
                    lab.getBackground().getGreen(), 
                    lab.getBackground().getBlue(), 
                    lab.getBackground().getAlpha()   steps));
                    if (lab.getBackground().getAlpha() == target) {
                        ((Timer) e.getSource()).stop();
                    }
                }
            });
            t.start();
        }
    }
    new Thread(new fade()).start();
}
  

вместо этого он просто переходит из черного в прозрачный. Ничего промежуточного. Это также выдает ошибку java.lang.IllegalArgumentException: Color parameter outside of expected range: Alpha . Однако я установил шаг в -5 (скорость, с которой он исчезает, в данном случае, исчезает, поскольку она отрицательна), и если вы помните, я установил альфа-значение, кратное пяти, и у меня также есть средство проверки того, когда он достигает цели, чтобы он останавливал таймер при достижении этой цели. Я что-то делаю не так? Слишком быстро обновляется фон JLabel, чтобы его можно было отобразить? Любая помощь была бы отличной.

Редактировать: я исправил java.lang.IllegalArgumentException: Color parameter outside of expected range: Alpha . Но другая о том, что JLabel не исчезает, все еще существует, и я не знаю, как это исправить.

Комментарии:

1. Вам нужно предоставить код, который я могу загрузить и запустить.

2. @Abra Я предоставлю столько кода, сколько вы захотите, или так мало. Могу я спросить, что все, что вам нужно?

3. Небольшая, полная программа, которая использует код, который вы уже опубликовали. Класс Java с main методом, который создает ваш графический интерфейс на Swing и запускает ваш код исчезновения надписей.

4. Вы ожидаете, что таймер запустит обратный вызов 10 раз?

Ответ №1:

Я не отвечаю прямо на ваш вопрос. A написал какой-то код, взгляните : D

 import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class MyWindow extends JFrame {

    public MyWindow() {
        initComponents();
    }

    private void initComponents() {

        setTitle( "Fading labels :)" );
        setDefaultCloseOperation( EXIT_ON_CLOSE );
        setSize( 400, 400 );
        setLocationRelativeTo( null );
        setLayout( new FlowLayout() );

        for ( int i = 0; i < 550; i   ) {
            JLabel lab = new JLabel( "x" );
            add( lab );
            fadeLabel( lab, 10, i / 10, 0 );
        }

    }

    private void fadeLabel( JLabel label, int steps, int skipSteps, int targetAlpha ) {
        new LabelFader( label, steps, skipSteps, targetAlpha ).start();
    }

    private class LabelFader {

        JLabel label;
        int steps;
        int skipSteps;
        int targetAlpha;

        LabelFader( JLabel label, int steps, int skipSteps, int targetAlpha ) {
            this.label = label;
            this.steps = steps;
            this.skipSteps = skipSteps;
            this.targetAlpha = targetAlpha;
        }

        void start() {

            Color startColor = label.getForeground();
            int startAlpha = startColor.getAlpha();
            int deltaAlpha = startAlpha - targetAlpha;

            if ( deltaAlpha > 0 ) {

                int alphaStep = deltaAlpha / steps;

                new Thread( new Runnable() {
                    @Override
                    public void run() {

                        int totalIterations = steps   skipSteps;
                        int currIteration = 1;

                        for ( int i = 0; i < totalIterations; i   ) {

                            if ( skipSteps == 0 ) {

                                int newAlpha = startAlpha - alphaStep * currIteration  ;
                                newAlpha = newAlpha < 0 ? 0 : newAlpha;

                                Color newColor = new Color( 
                                        startColor.getRed(), 
                                        startColor.getGreen(), 
                                        startColor.getGreen(),
                                        newAlpha );

                                label.setForeground( newColor );

                            } else {
                                skipSteps--;
                            }

                            try {
                                Thread.sleep( 100 );
                            } catch ( InterruptedException exc ) {
                                exc.printStackTrace();
                            }

                        }

                        Color newColor = new Color( 
                                startColor.getRed(), 
                                startColor.getGreen(), 
                                startColor.getGreen(),
                                targetAlpha );

                        label.setForeground( newColor );

                    }
                }).start();

            }

        }

    }

    public static void main( String[] args ) {
        EventQueue.invokeLater( new Runnable() {
            public void run() {
                new MyWindow().setVisible( true );
            }
        });
    }

}
  

Комментарии:

1. Спасибо, чувак, я попробую. Не уверен, что использование Thread.sleep(); является лучшим способом, но я попробую это.

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

3. можете ли вы сделать метод доступным и из других классов? @davidbuzzato

Ответ №2:

A JLabel по умолчанию не является непрозрачным, поэтому его фон не окрашен. Поэтому изменение цвета фона не будет иметь никакого эффекта — если вы явно не сделали свой JLabel непрозрачным, вызвав соответствующий метод, как в

 lab.setOpaque(true)
  

Простите меня, но я не смог найти этого в коде, который вы опубликовали.

Кроме того, код, влияющий на графический интерфейс пользователя, должен выполняться в потоке отправки событий (EDT). Ваш код, который изменяет JLabel цвет фона, выполняется в отдельном потоке. Следовательно, результат выполнения этого кода непредсказуем. javax.swing.Timer Класс не обязательно запускать в отдельном потоке. Просто создайте Timer объект, а затем вызовите его start метод. Итак, просто возьмите свой код, который создает Timer из Thread , и вставьте его в остальной код вашего GUI.

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

РЕДАКТИРОВАТЬ: Вот демонстрация, которая удаляет JLabel текст. A, JFrame содержащий a JLabel и a JButton . Нажмите на, JButton и JLabel текст исчезнет, пока не исчезнет совсем.

 import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.WindowConstants;

/**
 * Tests <i>Swing</i> {@link javax.swing.Timer timer}.
 */
public class LabelDim {
    private int alpha;
    private JButton button;
    private JFrame frame;
    private JLabel label;
    private Timer timer;

    public LabelDim() {
        timer = new Timer(200, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (alpha > 0) {
                    alpha -= 15;
                    label.setForeground(new Color(0, 0, 0, alpha));
                }
                else {
                    timer.stop();
                }
            }
        });
    }

    private void showGui() {
        frame = new JFrame("Dim");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        label = new JLabel("I am a fading label.", SwingConstants.CENTER);
        alpha = label.getForeground().getAlpha();
        label.setFont(label.getFont().deriveFont(24.0f));
        label.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
        frame.add(label, BorderLayout.CENTER);
        button = new JButton("Start");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                timer.start();
            }
        });
        JPanel panel = new JPanel();
        panel.add(button);
        frame.add(panel, BorderLayout.PAGE_END);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        LabelDim instance = new LabelDim();
        EventQueue.invokeLater(() -> instance.showGui());
    }
}
  

Комментарии:

1. Демонстрационная программа была бы прекрасной. И я уже установил непрозрачность JLabel в значение true, извините, что не учел это.

Ответ №3:

ВТОРАЯ ПРАВКА:

Вот несколько примеров кода, который работает. Это приведет к тому, Exception что вы уже исправили, но это только для демонстрационных целей :).

Поиграйте с label.setOpaque и его фоном и расскажите, что происходит с вами. Если вам нужно нарисовать фон метки, установите для этого флага значение true.

Если вам не нужно рисовать его фон, не изменяйте фон метки и не устанавливайте его непрозрачным, а изменения цвета переднего плана должно быть более чем достаточно ! 🙂

 package main;


import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Main extends JFrame {

    JLabel label;
    JButton btn;

    public Main() {
        setSize(500,500);
        setLayout(new FlowLayout());
        label = new JLabel("My super awesome label");
        //label.setOpaque(true); //Play with these lines and see what happens
        //label.setBackground(Color.BLUE); //Play with these lines and see what happens

        btn = new JButton("Click me");
        btn.setSize(200,200);
        btn.addActionListener(
                (ActionEvent evt) -> {
                    Timer t = new Timer(100,
                            (ActionEvent event) -> {
                                Color foreground = label.getForeground();
                                Color background = label.getBackground();

                                foreground = decreaseAlpha(foreground);
                                background = decreaseAlpha(background);

                                label.setForeground(foreground);
                                label.setBackground(background);
                            }
                        );

                    t.start();
                }
        );

        this.add(label);
        this.add(btn);
    }

    public static void main(String[] args) {
        (new Main()).setVisible(true);
    }

    public Color decreaseAlpha(Color original) {
        return new Color(original.getRed(), original.getGreen(), original.getBlue(), original.getAlpha() - 10);
    }
}
  

Редактировать:

Возможно, вы меняете фон своей метки вместо ее переднего плана…

 Timer t = new Timer(10, (ActionEvent evt)-> {
    l.setForeground(new 
        Color(l.getForeground().getRed(), 
        l.getForeground().getGreen(), 
        l.getForeground().getBlue(), 
        l.getForeground().getAlpha() - 1)
    );
    l.invalidate();
});
t.start();
  

Быть l вашим ярлыком

Кроме того, не делайте этого:

new Thread(new fade()).start();

Ваш fade класс уже является Thread , потому что он расширяет его. Используйте (new fade()).start(); вместо

Комментарии:

1. Я не ожидаю, что буду вызывать это 10 раз. Я понимаю, что между каждым запуском существует задержка в 10 миллисекунд, поэтому я добавил оператор if then, чтобы остановить это. У меня возникли проблемы с тем, почему JLabel не исчезает. Может быть, 10 мс — это слишком быстро для задачи?

2. нет, я точно знаю, что я всего лишь устанавливаю фон JLabel.

3. Да, и именно поэтому не работает. вместо этого вы должны установить передний план JLabel.

4. спасибо, я попробую. Но я думал, что передний план — это текст?

5. да, это просто текст. Я попробовал, JLabel был только белым и вообще не исчезал.