Сделать бег (шатер) JLabel в Netbeans [дубликат]

Симон Моурир дал этот пример :

object o = null;
DateTime d = (DateTime)o;  // NullReferenceException

, где unboxing преобразование (литье) из object (или из одного из классов System.ValueType или System.Enum или из типа интерфейса) - тип значения (кроме Nullable<>) сам по себе дает NullReferenceException.

В другом направлении конверсия бокса из a Nullable<>, которая имеет HasValue, равную false , на ссылочный тип, может дать ссылку null, которая затем может привести к NullReferenceException. Классический пример:

DateTime? d = null;
var s = d.ToString();  // OK, no exception (no boxing), returns ""
var t = d.GetType();   // Bang! d is boxed, NullReferenceException

Иногда бокс происходит по-другому. Например, с помощью этого не общего метода расширения:

public static void MyExtension(this object x)
{
  x.ToString();
}

следующий код будет проблематичным:

DateTime? d = null;
d.MyExtension();  // Leads to boxing, NullReferenceException occurs inside the body of the called method, not here.

Эти случаи возникают из-за специальных правил, используемых во время выполнения при боксе Nullable<> экземпляров.

10
задан bragboy 1 September 2010 в 12:25
поделиться

8 ответов

Вот пример с использованием javax.swing.Timer.

Marquee.png [/g0]

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

/** @see http://stackoverflow.com/questions/3617326 */
public class MarqueeTest {

    private void display() {
        JFrame f = new JFrame("MarqueeTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        String s = "Tomorrow, and tomorrow, and tomorrow, "
        + "creeps in this petty pace from day to day, "
        + "to the last syllable of recorded time; ... "
        + "It is a tale told by an idiot, full of "
        + "sound and fury signifying nothing.";
        MarqueePanel mp = new MarqueePanel(s, 32);
        f.add(mp);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        mp.start();
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new MarqueeTest().display();
            }
        });
    }
}

/** Side-scroll n characters of s. */
class MarqueePanel extends JPanel implements ActionListener {

    private static final int RATE = 12;
    private final Timer timer = new Timer(1000 / RATE, this);
    private final JLabel label = new JLabel();
    private final String s;
    private final int n;
    private int index;

    public MarqueePanel(String s, int n) {
        if (s == null || n < 1) {
            throw new IllegalArgumentException("Null string or n < 1");
        }
        StringBuilder sb = new StringBuilder(n);
        for (int i = 0; i < n; i++) {
            sb.append(' ');
        }
        this.s = sb + s + sb;
        this.n = n;
        label.setFont(new Font("Serif", Font.ITALIC, 36));
        label.setText(sb.toString());
        this.add(label);
    }

    public void start() {
        timer.start();
    }

    public void stop() {
        timer.stop();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        index++;
        if (index > s.length() - n) {
            index = 0;
        }
        label.setText(s.substring(index, index + n));
    }
}
24
ответ дан trashgod 31 August 2018 в 20:10
поделиться

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

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

MarqueePanel прокручивает компоненты на панели не только текст. Таким образом, это позволяет вам в полной мере использовать любой компонент Swing. Простую область выделения можно использовать, добавив JLabel с текстом. Вы можете добавить JLabel с HTML, чтобы вы могли использовать разные шрифты и цвет для текста. Вы даже можете добавить второй компонент с изображением.

6
ответ дан camickr 31 August 2018 в 20:10
поделиться

Вот код, который я собрал вместе, чтобы вы начали. Обычно я бы взял код ActionListener и поместил его в какой-то класс MarqueeController, чтобы сохранить эту логику отдельно от панели, но это другой вопрос об организации архитектуры MVC, и в достаточно простом классе, как это, может быть, так что важно.

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

public class MarqueePanel extends JPanel {
  private JLabel textLabel;
  private int panelLocation;
  private ActionListener taskPerformer;
  private boolean isRunning = false;

  public static final int FRAMES_PER_SECOND = 24;
  public static final int MOVEMENT_PER_FRAME = 5;

  /**
   * Class constructor creates a marquee panel.
   */

  public MarqueePanel() {
    this.setLayout(null);
    this.textLabel = new JLabel("Scrolling Text Here");
    this.panelLocation = 0;
    this.taskPerformer = new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        MarqueePanel.this.tickAnimation();
      }
    }
  }

  /**
   * Starts the animation.
   */

  public void start() {
    this.isRunning = true;
    this.tickAnimation();
  }

  /**
   * Stops the animation.
   */

  public void stop() {
    this.isRunning = false;
  }

  /**
   * Moves the label one frame to the left.  If it's out of display range, move it back
   * to the right, out of display range.
   */

  private void tickAnimation() {
    this.panelLocation -= MarqueePanel.MOVEMENT_PER_FRAME;
    if (this.panelLocation < this.textLabel.getWidth())
      this.panelLocaton = this.getWidth();
    this.textLabel.setLocation(this.panelLocation, 0);
    this.repaint();
    if (this.isRunning) {
      Timer t = new Timer(1000 / MarqueePanel.FRAMES_PER_SECOND, this.taskPerformer);
      t.setRepeats(false);
      t.start();
    }
  }
}
1
ответ дан Erick Robertson 31 August 2018 в 20:10
поделиться

Основной ответ заключается в том, что вы рисуете текст / графику в растровое изображение, а затем реализуете компонент, который рисует смещение битмапа на какую-то сумму. Обычно шатры / тикеры прокручиваются влево, так что смещение увеличивается, что означает, что растровое изображение окрашено в -offset. Ваш компонент запускает таймер, который периодически срабатывает, увеличивая смещение и аннулируя его, чтобы он перекраивался.

Такие вещи, как упаковка, немного сложнее иметь дело, но довольно просто. Если смещение превышает ширину растрового изображения, вы возвращаете его обратно на 0. Если ширина смещения + ширина компонента> ширина растрового изображения вы рисуете остаток компонента, начиная с начала растрового изображения.

Ключ к приличному тикеру - сделать прокрутку гладкой и максимально мерцающей. Поэтому может потребоваться рассмотреть двойную буферизацию результата, сначала нарисуя прокручивающийся бит в растровое изображение, а затем визуализируя это за один раз, а не рисуя прямо на экране.

1
ответ дан locka 31 August 2018 в 20:10
поделиться

Я только что зашел в Google и нашел эту ссылку . Я запустил код и, похоже, сделал то, что вы хотите.

1
ответ дан Noel M 31 August 2018 в 20:10
поделиться

Добавить JLabel к вашему фрейму или панели.

ScrollText s=   new ScrollText("ello Everyone.");
jLabel3.add(s);


public class ScrollText extends JComponent {
private BufferedImage image;

private Dimension imageSize;

private volatile int currOffset;

private Thread internalThread;

private volatile boolean noStopRequested;

public ScrollText(String text) {
currOffset = 0;
buildImage(text);

setMinimumSize(imageSize);
setPreferredSize(imageSize);
setMaximumSize(imageSize);
setSize(imageSize);

noStopRequested = true;
Runnable r = new Runnable() {
  public void run() {
    try {
      runWork();
    } catch (Exception x) {
      x.printStackTrace();
    }
  }
};

internalThread = new Thread(r, "ScrollText");
internalThread.start();
}

private void buildImage(String text) {
RenderingHints renderHints = new RenderingHints(
    RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_ON);

renderHints.put(RenderingHints.KEY_RENDERING,
    RenderingHints.VALUE_RENDER_QUALITY);

BufferedImage scratchImage = new BufferedImage(1, 1,
    BufferedImage.TYPE_INT_RGB);

Graphics2D scratchG2 = scratchImage.createGraphics();
scratchG2.setRenderingHints(renderHints);

Font font = new Font("Serif", Font.BOLD | Font.ITALIC, 24);

FontRenderContext frc = scratchG2.getFontRenderContext();
TextLayout tl = new TextLayout(text, font, frc);
Rectangle2D textBounds = tl.getBounds();
int textWidth = (int) Math.ceil(textBounds.getWidth());
int textHeight = (int) Math.ceil(textBounds.getHeight());

int horizontalPad = 600;
int verticalPad = 10;

imageSize = new Dimension(textWidth + horizontalPad, textHeight
    + verticalPad);

image = new BufferedImage(imageSize.width, imageSize.height,
    BufferedImage.TYPE_INT_RGB);

Graphics2D g2 = image.createGraphics();
g2.setRenderingHints(renderHints);

int baselineOffset = (verticalPad / 2) - ((int) textBounds.getY());

g2.setColor(Color.BLACK);
g2.fillRect(0, 0, imageSize.width, imageSize.height);

g2.setColor(Color.GREEN);
tl.draw(g2, 0, baselineOffset);

// Free-up resources right away, but keep "image" for
// animation.
scratchG2.dispose();
scratchImage.flush();
g2.dispose();
 }
public void paint(Graphics g) {
// Make sure to clip the edges, regardless of curr size
g.setClip(0, 0, imageSize.width, imageSize.height);

int localOffset = currOffset; // in case it changes
g.drawImage(image, -localOffset, 0, this);
g.drawImage(image, imageSize.width - localOffset, 0, this);

// draw outline
g.setColor(Color.black);
g.drawRect(0, 0, imageSize.width - 1, imageSize.height - 1);
  }
private void runWork() {
while (noStopRequested) {
  try {
    Thread.sleep(10); // 10 frames per second

    // adjust the scroll position
    currOffset = (currOffset + 1) % imageSize.width;

    // signal the event thread to call paint()
    repaint();
  } catch (InterruptedException x) {
    Thread.currentThread().interrupt();
  }
  }
 }

public void stopRequest() {
noStopRequested = false;
internalThread.interrupt();
}

public boolean isAlive() {
return internalThread.isAlive();
}


}
0
ответ дан Raghunandan 31 August 2018 в 20:10
поделиться

Предполагается, что это будет улучшение @mamickr MarqueePanel. См. Выше.

Чтобы сопоставить события мыши с конкретными компонентами, добавленными в MarqueePanel

Переопределить add(Component comp) MarqueePanel, чтобы направить все события мыши компонентов

Проблема в том, что делать с MouseEvents, выпущенным из отдельных компонентов. Мой подход состоит в том, чтобы удалить слушателей мыши из добавленных компонентов и позволить MarqueePanel перенаправить событие на правильный компонент.

В моем случае эти компоненты должны быть ссылками.

    @Override
    public Component add(Component comp) {
        comp = super.add(comp);

        if(comp instanceof MouseListener)
             comp.removeMouseListener((MouseListener)comp);

        comp.addMouseListener(this);

        return comp;
    }

Затем отобразите компонент x в MarqueePanel x и, наконец, верную компоненту

@Override
public void mouseClicked(MouseEvent e)
{
    Component source = (Component)e.getSource();
    int x = source.getX() + e.getX();
    int y = source.getY();

    MarqueePanel2 marqueePanel = (MarqueePanel2) ((JComponent)e.getSource()).getParent();
    double x2 = marqueePanel.getWidth();
    double x1 = Math.abs(marqueePanel.scrollOffset);



    if(x >= x1 && x <= x2)
    {
        System.out.println("Bang " + x1);
        Component componentAt = getComponentAt(x+marqueePanel.scrollOffset, y);

        if(comp instanceof MouseListener)
             ((MouseListener) componentAt).mouseClicked(e);

        System.out.println(componentAt.getName());
    }
    else
    {
        return;
    }


    //System.out.println(x);
}
0
ответ дан Spiff 31 August 2018 в 20:10
поделиться
Другие вопросы по тегам:

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