【问题标题】:scala swing: draggable / resizable component traitscala swing:可拖动/可调整大小的组件特征
【发布时间】:2011-04-23 06:04:56
【问题描述】:

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

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

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

【问题讨论】:

  • 我认为这可以通过一些特殊的面板/布局来实现,但不能直接在组件上,组件的大小和位置取决于您放入的面板类型。

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


【解决方案1】:

我在我当前的项目中使用这些。您可能需要用自己的 Vector 库替换并添加隐式定义。或者使用挥杆中的点/尺寸。组件需要位于允许自定义位置和大小的面板中,例如来自 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
    }
}

【讨论】:

    【解决方案2】:

    我所知道的唯一可拖动和可调整大小的组件是 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 包中,需要手动包装。

    【讨论】:

      猜你喜欢
      • 2011-04-29
      • 2011-12-19
      • 1970-01-01
      • 1970-01-01
      • 2014-01-16
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多