jruby + swing で画像閲覧
- http://terai.xrea.jp/Swing/Zoom.html
> > MouseWheelで画像のズームイン・アウト表示 - Java Swing Tips
のプログラムをベースに、少し拡張してみた。
// darg & drop で画像を入れ替えたり、
// マウスで画像をつかんでスクルールさせるなど..
起動時には最初、ainomukidashi.jpg を表示している。
// 2009-03-22 19:00 ソースコードを差し替えた。
$ cat wheel.rb
# See - http://terai.xrea.jp/Swing/Zoom.html
# MouseWheelで画像のズームイン・アウト表示 - Java Swing Tips
# 2009-03-21 katoy
# - デスクトップなどから、File を Drop して、表示ファイルを切り替えることが可能。
# - MouseWheelで画像のズームイン・アウトする。
# - Mouse ドラッグでもスクロールできる。
# - Mouse クリックすると、そこが表示中心になる。
require 'java'
require 'pp'
import java.awt.BorderLayout
import java.awt.Dimension
import java.awt.Graphics2D
import java.awt.Point
import java.awt.Rectangle
import java.awt.Cursor
import java.awt.event.ActionListener
import java.awt.event.MouseListener
import java.awt.datatransfer.DataFlavor
import java.awt.dnd.DnDConstants
import java.awt.dnd.DropTarget
import java.awt.dnd.DropTargetAdapter
import java.awt.dnd.DropTargetListener
import javax.swing.JFrame
import javax.swing.JPanel
import javax.swing.JScrollPane
import javax.swing.JButton
import javax.swing.UIManager
import javax.swing.JComponent
import javax.swing.AbstractAction
import javax.swing.ImageIcon
import javax.swing.Box
START_ICON_PATH = 'ainomukidashi.jpg'
class MainPanel < JPanel
def initialize
super(BorderLayout.new)
icon = ImageIcon.new(START_ICON_PATH)
zoom = ZoomImage.new
zoom.setIcon(icon)
scrollpane = JScrollPane.new(zoom)
vport = scrollpane.getViewport
vport.addMouseWheelListener(MyWheelListener.new(zoom, vport))
mml = MyMouseListener.new
mml.setZoom(zoom, vport)
vport.addMouseMotionListener(mml)
vport.addMouseListener(mml)
dta = MyDropTargetAdapter.new
dta.setZoom(zoom)
DropTarget.new(zoom, dta)
button1 = RButton.new("Zoom In") { zoom.changeScale(-5, vport) }
button2 = RButton.new("Zoom Out") { zoom.changeScale(5, vport) }
button3 = RButton.new("Original size") { zoom.initScale(vport) }
box = Box.createHorizontalBox()
box.add(Box.createHorizontalGlue())
box.add(button1)
box.add(button2)
box.add(button3)
add(scrollpane)
add(box, BorderLayout::SOUTH)
end
end
class RButton < JButton
def initialize(text)
super(text)
self.addActionListener Proc.new if block_given?
end
end
class MyDropTargetAdapter < DropTargetAdapter
def setZoom(zoom)
@zoom = zoom
end
def drop(e)
transfer = e.getTransferable();
if transfer.isDataFlavorSupported(DataFlavor.javaFileListFlavor)
e.acceptDrop(DnDConstants::ACTION_COPY_OR_MOVE)
fileList = transfer.getTransferData(DataFlavor.javaFileListFlavor)
icon = ImageIcon.new(fileList[0].getAbsolutePath())
@zoom.setIcon(icon)
end
end
end
class MyWheelListener
include java.awt.event.MouseWheelListener
def initialize(zoom, vport)
@zoom = zoom
@vport = vport
end
def mouseWheelMoved(e)
@zoom.changeScale(e.getWheelRotation() * 0.6, @vport)
end
end
class MyMouseListener < javax.swing.event.MouseInputAdapter
def initialize
@pp = Point.new
end
def setZoom(zoom, vport)
@zoom = zoom
@vport = vport
@defCursor = Cursor::getPredefinedCursor(Cursor::DEFAULT_CURSOR)
@hndCursor = Cursor::getPredefinedCursor(Cursor::HAND_CURSOR)
end
def mouseDragged(e)
cp = e.getPoint()
vp = @vport.getViewPosition()
vp.translate(@pp.x - cp.x, @pp.y - cp.y)
@zoom.scrollRectToVisible(Rectangle.new(vp, @vport.getSize))
@pp.setLocation(cp)
end
def mouseClicked(e)
cp = e.getPoint()
size = @vport.getSize
vp = @vport.getViewPosition
vp.translate(cp.x - size.width / 2, cp.y - size.height / 2)
@zoom.scrollRectToVisible(Rectangle.new(vp, @vport.getSize))
end
def mousePressed(e)
@zoom.setCursor(@hndCursor)
@pp.setLocation(e.getPoint())
end
def mouseReleased(e)
@zoom.setCursor(@defCursor)
end
end
class ZoomImage < JComponent
attr_reader :scale
def initialize
super
end
def setIcon(icon)
@icon = icon
@iw = icon.getIconWidth * 1.0
@ih = icon.getIconHeight * 1.0
@scale = 1.0
revalidate
repaint
end
def paintComponent(g)
g.scale(@scale, @scale)
g.drawImage(@icon.getImage, 0, 0, @iw, @ih, self)
end
def getPreferredSize
Dimension.new(@iw * @scale, @ih * @scale)
end
def initScale(vport)
@scale = 1.0
setPreferredSize(Dimension.new(@iw * @scale, @ih * @scale))
scrollRectToVisible(Rectangle.new(Point.new(0, 0), size))
revalidate
repaint
end
def changeScale(iv, vport)
old_scale = @scale
@scale = java.lang.Math.max(0.05, java.lang.Math.min(5.0, @scale - iv * 0.05))
pos = vport.getViewPosition
size = vport.getSize
# 古い scale で, 表示中心を求めてから、新しい scale での 表示左上端を座標を求める。
cx = @scale * (pos.x / old_scale + size.width / 2.0 / old_scale - size.width / 2.0 / @scale)
cy = @scale * (pos.y / old_scale + size.height/ 2.0 / old_scale - size.height/ 2.0 / @scale)
setPreferredSize(Dimension.new(@iw * @scale, @ih * @scale))
scrollRectToVisible(Rectangle.new(Point.new(cx, cy), size))
revalidate
repaint
end
end
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName)
frame = JFrame.new("Zoom")
frame.get_content_pane.add(MainPanel.new)
frame.set_default_close_operation(JFrame::EXIT_ON_CLOSE)
frame.pack
# フレームをデスクトップの中央に表示
frame.setLocationRelativeTo(nil)
frame.visible = true
最近のコメント