0

Is there a Java-only way to show larger pictures in a JScrollPane? I don't want to reinvent the wheel and I'm already struggling at showing 32768x400 images using the ImageIcon in a JLabel trick because there seem to be limits regarding the ImageIcon that are platform dependent. Ubuntu 16.10 won't show any ImageIcon of the size 32768x400, though it shows smaller ones. Win10 shows them all.... and there is not even any error output of any sorts, which is terrible because I just wasted time searching for the problem.

So is there any easy solution to this that does not require me to reinvent the wheel?

In particular, I want to display waveforms, ie. an array of floats, so there is actually no need to have an overall image at all.

user1050755
  • 11,218
  • 4
  • 45
  • 56
  • Have you tried creating a `JPanel` and overriding it's `paintComponent` and `getPreferredSize` methods to draw the image yourself? The second [example](http://stackoverflow.com/questions/22162398/how-to-set-a-background-picture-in-jpanel/22162430#22162430) demonstrates the basic concept. This may not work, but it's worth a try to see if it's an issue with `JLabel` or Ununtu – MadProgrammer Jan 18 '17 at 21:01
  • that's the next step I'd do, tho I'd rather avoid and use some more advanced stuff that's possibly already out there. – user1050755 Jan 18 '17 at 21:02
  • *"In particular, I want to display waveforms"* - You mean something like [this](http://stackoverflow.com/questions/27517265/graphing-wav-file-in-java/27517678#27517678) or [this](http://stackoverflow.com/questions/12066698/gui-freezes-when-drawing-wave-from-animation-on-jpanel-though-i-used-swing-timer/12066748#12066748)? You still need to generate some kind of image and it might be a limitation of Ubuntu – MadProgrammer Jan 18 '17 at 21:04
  • The direct answer to your primary question as stated is actually "Yes, there is a way; put it in a JScrollPane." But it appears you tried that and are having problems. I clicked this question because it was misleading (not going to downvote though). You might want to rephrase your question (both the title, and the ending one-line paragraph) to fit better the description you gave for your problem, especially if you want to attract the kind of people that are more likely to be able to answer it. Otherwise you'll get a lot of people like me dropping in to almost say "Put it in a JScrollPane." – Loduwijk Jan 18 '17 at 21:05
  • @MadProgrammer You quote the question-asker as saying "In particular, I want to display waveforms," where are you getting that quote from? I don't see it in the question or the comments. – Loduwijk Jan 18 '17 at 21:06
  • No you don't need an Image, you can override the paint methods and draw stuff directly from the source data. – user1050755 Jan 18 '17 at 21:07
  • @Aaron Refresh the question, it was added after the question was originally asked...right at the bottom ;) – MadProgrammer Jan 18 '17 at 21:07
  • @user1050755 Which, through the magic of the paint process generates a BMP for the OS to render, an image is generated at some point - how big that image is, is another question ;) – MadProgrammer Jan 18 '17 at 21:08
  • #user1050755 All the proponents of the "Label trick" are here: why dont you ask them directly on the face?? maybe try a Timer...a Swing Worker? try overiding that pain method...no?? ........ then I'm out of bag tricks – gpasch Jan 18 '17 at 22:16

1 Answers1

2

I believe this shows how to do what you want. Note how the Graph component has a width of 65535. This could be further optimized by only drawing the visible part of the graph as you scroll, but it's fairly fast as it is.

import java.awt.*;
import javax.swing.*;
import java.util.function.Function;

class Graph extends JComponent {
  private Function<Double, Double> fun;

  public Graph(Function<Double, Double> fun) {
    this.fun = fun;
    setPreferredSize(new Dimension(65535, 300));
  }

  public void paintComponent(Graphics g) {
    // clear background
    g.setColor(Color.white);
    Rectangle bounds = getBounds();
    int w = bounds.width;
    int h = bounds.height;
    g.fillRect(bounds.x, bounds.y, w, h);
    // draw the graph
    int prevx = 0;
    int prevy = fun.apply((double)prevx).intValue();
    g.setColor(Color.black);
    for (int i=1; i<w; i++) {
      int y = fun.apply((double)i).intValue();
      g.drawLine(prevx, prevy, i, y);
      prevx = i;
      prevy = y;
    }
  }
}

public class Wf {
  public static void main(String[] args) {
   JFrame f = new JFrame();
   // we're going to draw A sine wave for the width of the 
   // whole Graph component
   Graph graph = new Graph(x -> Math.sin(x/(2*Math.PI))*100+200);
   JScrollPane jsp = new JScrollPane(graph);
   f.setContentPane(jsp);
   f.setSize(800, 600);
   f.setVisible(true);
  }
}
Roberto Attias
  • 1,883
  • 1
  • 11
  • 21