scala swing:可拖动/可调整大小的组件特征

时间:2011-04-23 06:04:57

标签: swing scala drag-and-drop resize position

我正在寻找一个可以混合到scala.swing.Component的scala特征,它将允许使用鼠标输入定位和调整该组件的大小。

理想情况下,它会添加小框作为“句柄”,以向用户指示可以调整组件的大小: enter image description here

我觉得这是一项相当普遍的任务,应该有一些支持它的特性。

2 个答案:

答案 0 :(得分:5)

我在我当前的项目中使用这些。您可能需要使用自己的Vector库替换Vector库并添加含义defs。或者从挥杆中使用点/尺寸。组件需要位于允许自定义位置和大小的面板中,例如来自http://dgronau.wordpress.com/2010/08/28/eine-frage-des-layouts/的NullPanel

trait Movable extends Component{
    var dragstart:Vec2i = null
    listenTo(mouse.clicks, mouse.moves)
    reactions += {
        case e:MouseDragged =>
            if( dragstart != null )
                peer.setLocation(location - dragstart + e.point)
        case e:MousePressed =>
            this match {
                case component:Resizable =>
                    if( component.resizestart == null )
                        dragstart = e.point
                case _ =>
                    dragstart = e.point

            }
        case e:MouseReleased =>
            dragstart = null    
    }
}

trait Resizable extends Component{
    var resizestart:Vec2i = null
    var oldsize = Vec2i(0)
    def resized(delta:Vec2i) {}
    listenTo(mouse.clicks, mouse.moves)
    reactions += {
        case e:MouseDragged =>
            if( resizestart != null ){
                val delta = e.point - resizestart
                peer.setSize(max(oldsize + delta, minimumSize))

                oldsize += delta
                resizestart += delta

                resized(delta)
                revalidate
            }
        case e:MousePressed =>
            if( size.width - e.point.x < 15
             && size.height - e.point.y < 15 ){
                resizestart = e.point
                oldsize = size

                this match {
                    case component:Movable =>
                        component.dragstart = null
                    case _ =>
                }
            }
        case e:MouseReleased =>
            resizestart = null
    }
}

答案 1 :(得分:0)

我知道的唯一可用的是可拖动和可调整大小的组件是JDesktop上的InternalFrame。这是一个例子:

import swing._
import event._

import javax.swing.{UIManager,JComponent}
import javax.swing.KeyStroke.getKeyStroke
import java.awt.{Graphics2D,Graphics}

object InternalFrameDemo extends SimpleSwingApplication{
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName)

    val top = new MainFrame{
        title = "InternalFrameDemo"
        preferredSize = new Dimension(640,480)
        val desktop = new javax.swing.JDesktopPane

        val jc = new JComponent{
            override def paint(g:Graphics){
                import g._
                drawLine(0,0,20,20)
                drawLine(0,20,20,0)
                println("yay draw")
            }

            setVisible(true)
        }

        desktop add jc

        contents = Component.wrap(desktop)

        menuBar = new MenuBar{
            contents += new Menu("Document"){
                mnemonic = Key.D

                contents += new MenuItem("New"){
                    mnemonic = Key.N
                    action = new Action("new"){
                        def apply = createFrame
                        accelerator = Some(getKeyStroke("alt N"))
                    }
                }

                contents += new MenuItem("Quit"){
                    mnemonic = Key.Q
                    action = new Action("quit"){
                        def apply(){
                            quit()
                        }
                        accelerator = Some(getKeyStroke("alt Q"))
                    }
                }
            }
        }

        def createFrame{
            val newFrame = MyInternalFrame()
            newFrame setVisible true
            desktop add newFrame
            newFrame setSelected true

        }
    }
}

import javax.swing.{JDesktopPane,JInternalFrame}
import collection.mutable.ArrayBuffer

object MyInternalFrame{
    var openFrameCount = 0;
    val xOffset, yOffset = 30;

    def apply() = {
        openFrameCount += 1
        val jframe = new javax.swing.JInternalFrame("Document #" + openFrameCount,true,true,true,true)

        jframe.setSize(300,300)
        jframe.setLocation(xOffset*openFrameCount,yOffset*openFrameCount)

        jframe //Component.wrap(jframe)
    }
}

但是JInternalFrame和JDesktop都未集成在scala swing包中,需要手动包装。