Graphics with Canvas or JComponent ?

Joe

Thành viên VIP
21/1/13
3,074
1,344
113
(Continue of HERE)

Graphics with CANVAS or JCOMPONENT?

Online Sales are only attractive if the selling articles are visually presented. The more beautiful an image it, the more attractive it appears to the consumers. Too complex presentation could reverse the effect and becomes negative when the viewers have to "try" how to "handle" the image. For example, most of car companies offer the potential buyers the Configurator tool so that the viewers could toy with the image of the car. 180° rotation or Zoom In/out, etc. Well, that is quite OK because it's about a "luxury article" and people won't buy a car for fun and throw it away if they found some details that displease them. However, the mentioned technique works sometime badly. Too long for a rotation move and then suddenly as if the rotation was in haste. The main problem of the glitch is the browser together with the upload of images. Browser must interpret the HTML/JS pages and if the pages are either too big, or too redundantly coded the browser becomes sluggish. And then the upload of pictures, the resizing of images (rotate, zoom, etc.) is executed interpretively. All that requires a real high-end computer, not an average home computer. Two problems that most developers are usually unaware about are the functional discrepancy between the browsers and the interpretation of the browsers. Some pages work with this browser, but fail in the others and the worst is the performant dependence on the browsers.

So, if the application developers work at his office with their high-end workstation they won't see the intermittent glitches. It's the problem of the project leader and of the company that won't let the developers develop, but coerce them to run some licensed tools that produce real fantastic appearances, but the produced HTML/JS codes are in some cases too redundant or simply superfluous and almost impossible to maintain. Some simple examples:
  • Laravel: Laravel is a complex package that requires its "users" to know "everything a bit": JS, JSON, PHP. And PHP was firstly envisaged as Personal Home Page language, and later gets the new interpretation as the Hypertext Preprocessor acronym in reverse. Whatever Laravel is PHP is originally the "personal" programming language that is therefore more cryptic than even C++ and later to an OOPL converted. If you are interested in this issue click HERE to learn some Laravel coding examples.
  • Spring Framework: the tool produces a bundles of files that the developers have a lot of troubles to work with: model, controller, JSP, etc. A good memorizing of myriad "annotations" for the models and controllers is indispensable.
  • IDE Netbeans: the Intergrated Development Environment tool. For a GUI design it is just the matter of clicking on the icons. Click HERE to see how the Netbeans GUI Builder work.
Some application developers are quite adept with the tools, but somehow they are blind or unable to read the generated codes or to edit them manually for enhancement or correction. The question is then: how can the HTML/JS pages work optimally on the consumer site?

I have shown you in the previous session how to serialize an image content to a String (rather than keeping it as a byte[]) and stored it in together with other objects in an OODB. The advantage is that there is no need to know the physical location of the image file (with the absolute Path). The image becomes an accessible object during the runtime and it can be read or sent over the Web to the consumers where (on the customer computer) the images can be locally processed: Zoom-In/Out, rotate or even animation. And the screenshot HERE gives you an idea how the Zooming works.

ImageZooming.png

Or an image can be easily rotated as following :
Java:
// Joe Nartca (C)
public class ImageRotate extends JButton {
  public static void main(String[] args) throws Exception {
    String pic = args.length > 0? args[0]:"boss.jpg";
    BufferedImage img = toImage(imageString(pic));
    ImageRotate ir = new ImageRotate(img);
    ir.addActionListener(e -> {
      ir.anew( );
    });
    w = img.getWidth()+10;
    h = img.getHeight()+10;
    if (w > h) h = w;
    else if (h > w) w = h;
    JFrame frame = new JFrame("Image & String");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add("Center", ir);
    frame.setSize(w, h);
    frame.setVisible(true);
  }
  public ImageRotate(BufferedImage img) {
   this.img = img;
  }
  public void anew() {
    angle += 0.10;
    repaint();
  }
  public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.setColor(Color.black);
    g2d.fillRect(0, 0, w, h);
    g2d.setColor(Color.white);
    g2d.rotate(angle, w/2, h/2);
    g2d.drawImage(img, 5, 5, this);
  }
  private static int w, h;
  private BufferedImage img;
  private static double angle = 0;
  // convert Image to ImageString
  public static String imageString(String image) {
    try {
      byte[] bb = Files.readAllBytes((new File(image)).toPath());
      StringBuilder sb = new StringBuilder(bb.length);
      for (byte b : bb) sb.append((char)(b & 0xFF));
      return sb.toString();
    } catch (Exception ex) { }
    return image;
  }
  // Convert ImageString back to BufferedImage
  public static BufferedImage toImage(String image) {
    try {
      ByteArrayOutputStream bao = new ByteArrayOutputStream();
      for (int i = 0, len = image.length(); i < len; ++i) {
        bao.write(new byte[] { (byte)image.charAt(i) } );
      }
      return ImageIO.read(new ByteArrayInputStream(bao.toByteArray()));
    } catch (Exception ex) { }
    return null;
  }
}
Every time you click on the image the image starts to rotate at 0.10 radian.

ImageRotate.png

This way saves not only time, but also gets rid of some the possible glitches. You may wonder why Canvas is not used instead of JComponent (or JButton as an extension of JComponent)? Canvas needs a certain buffering strategy to make sure that the display won't flicker. For example, two BufferedImages which are alternately activated could help. And that makes the implementation more complex. That is why Graphics with JComponent is the preferred choice. Further, the display is usually not purposed for the animations, but it should react only whenever the viewer clicks on it.

JButton is an extension of JComponent and it can react to a defined ClickOnActionEvent while Canvas is an extension of Component and needs an extra component that only reacts to a ClickOnActionEvent and triggers a certain action off Canvas. Example:
Java:
// Joe Nartca (C)
public class CanvasRotate extends Canvas {
  public static void main(String[] args) throws Exception {
    String pic = args.length > 0? args[0]:"boss.jpg";
    BufferedImage img = toImage(imageString(pic));
    w = img.getWidth()+10;
    h = img.getHeight()+10;
    if (w > h) h = w;
    else if (h > w) w = h;
    CanvasRotate cr = new CanvasRotate(img);
    // need a Button to make the rotation
    JButton but = new JButton("ROTATE");
    but.addActionListener(e -> {
      cr.anew( );
    });
    JFrame frame = new JFrame("Image & String");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel jp = new JPanel();
    jp.add(but);
    jp.add(cr);
    frame.add("Center", jp);
    frame.setSize(w, h+10);
    frame.setVisible(true);
  }
  public CanvasRotate(BufferedImage img) {
    setPreferredSize(new Dimension(w, h));
    this.img = img;
  }
  public void anew() {
    angle += 0.10;
    repaint( );
  }
  // neccessary for a stable presentation
  public void update(Graphics g) {
    paint(g);
  }
  public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setColor(Color.black);
    g2d.fillRect(0, 0, w, h);
    g2d.setColor(Color.white);
    g2d.rotate(angle, w/2, h/2);
    g2d.drawImage(img, 5, 5, this);
  }
  private static int w, h;
  private BufferedImage img;
  private static double angle = 0;
  // convert Image to ImageString
  public static String imageString(String image) {
    try {
      byte[] bb = Files.readAllBytes((new File(image)).toPath());
      StringBuilder sb = new StringBuilder(bb.length);
      for (byte b : bb) sb.append((char)(b & 0xFF));
      return sb.toString();
    } catch (Exception ex) { }
    return image;
  }
  // Convert ImageString back to BufferedImage
  public static BufferedImage toImage(String image) {
    try {
      ByteArrayOutputStream bao = new ByteArrayOutputStream();
      for (int i = 0, len = image.length(); i < len; ++i) {
        bao.write(new byte[] { (byte)image.charAt(i) } );
      }
      return ImageIO.read(new ByteArrayInputStream(bao.toByteArray()));
    } catch (Exception ex) { }
    return null;
  }
}
CanvasRotate.png

Talking about Graphics one may think about 3D Graphics. JAVA 3D is also available and you can download the 3D package from HERE. The 3D Tutorials can be found HERE for Part I or HERE and HERE for Part II.

(continue HERE)
 
Sửa lần cuối: